[GH-ISSUE #509] Page.SwitchToPage doesn't work in goruntine #367

Closed
opened 2026-03-04 01:04:23 +03:00 by kerem · 2 comments
Owner

Originally created by @ledongthuc on GitHub (Oct 4, 2020).
Original GitHub issue: https://github.com/rivo/tview/issues/509

I plan to change page automatically after period time from goroutine. But it doesn't work

Env:

GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/thucle/Library/Caches/go-build"
GOENV="/Users/thucle/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/thucle/.gvm/pkgsets/go1.15.2/global/pkg/mod"
GONOPROXY="github.com/liminaab/monorepo"
GONOSUMDB="github.com/liminaab/monorepo"
GOOS="darwin"
GOPATH="/Users/thucle/.gvm/pkgsets/go1.15.2/global"
GOPRIVATE="github.com/liminaab/monorepo"
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/Users/thucle/.gvm/gos/go1.15.2"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/Users/thucle/.gvm/gos/go1.15.2/pkg/tool/darwin_amd64"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/thucle/Projects/ledongthuc/secretsmanagerui/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/j8/n4yx0d492pg7v2kvj7203d_c0000gn/T/go-build815956428=/tmp/go-build -gno-record-gcc-switches -fno-common"
OS: Mac OS Catalina
Terminal: Iterm 2. Build 3.3.12
	fyne.io/fyne v1.3.3
	github.com/gizak/termui/v3 v3.1.0 // indirect
	github.com/rivo/tview v0.0.0-20200915114512-42866ecf6ca6 // indirect

Expected:

It still works if we use button to switch page.

Code:

// Demo code for the Pages primitive.
package main

import (
	"strings"
	"time"

	"github.com/gdamore/tcell"
	"github.com/rivo/tview"
)

const pageCount = 5

func main() {
	app := tview.NewApplication()
	pages := tview.NewPages()

	/* Table */
	table := tview.NewTable().
		SetBorders(true)
	lorem := strings.Split("Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.", " ")
	cols, rows := 10, 40
	word := 0
	for r := 0; r < rows; r++ {
		for c := 0; c < cols; c++ {
			color := tcell.ColorWhite
			if c < 1 || r < 1 {
				color = tcell.ColorYellow
			}
			table.SetCell(r, c,
				tview.NewTableCell(lorem[word]).
					SetTextColor(color).
					SetAlign(tview.AlignCenter))
			word = (word + 1) % len(lorem)
		}
	}
	flexTable := tview.NewFlex().SetDirection(tview.FlexRow).
		AddItem(tview.NewBox().SetBorder(true).SetTitle("AWS info"), 0, 1, false).
		AddItem(tview.NewBox().SetBorder(true).SetTitle("Searching"), 0, 2, false).
		AddItem(table, 0, 2, false)
	pages.AddPage("table", flexTable, true, false)

	/* Form */
	form := tview.NewForm().
		AddDropDown("Title", []string{"Mr.", "Ms.", "Mrs.", "Dr.", "Prof."}, 0, nil).
		AddInputField("First name", "", 20, nil, nil).
		AddInputField("Last name", "", 20, nil, nil).
		AddCheckbox("Age 18+", false, nil).
		AddPasswordField("Password", "", 10, '*', nil).
		AddButton("Quit", func() {
			pages.SwitchToPage("table")
		})
	form.SetBorder(true).SetTitle("Enter some data").SetTitleAlign(tview.AlignLeft)
	flex := tview.NewFlex().SetDirection(tview.FlexRow).
		AddItem(tview.NewBox().SetBorder(true).SetTitle("AWS info"), 0, 1, false).
		AddItem(tview.NewBox().SetBorder(true).SetTitle("Searching"), 0, 2, false).
		AddItem(form, 0, 2, false)
	pages.AddPage("form", flex, true, true)

	/* Auto change from Form page to Table page after 5 seconds */
	go func() {
		time.Sleep(5 * time.Second)
		pages.SwitchToPage("table")
	}()

	if err := app.SetRoot(pages, true).EnableMouse(true).Run(); err != nil {
		panic(err)
	}
}

Originally created by @ledongthuc on GitHub (Oct 4, 2020). Original GitHub issue: https://github.com/rivo/tview/issues/509 I plan to change page automatically after period time from goroutine. But it doesn't work Env: ``` GO111MODULE="" GOARCH="amd64" GOBIN="" GOCACHE="/Users/thucle/Library/Caches/go-build" GOENV="/Users/thucle/Library/Application Support/go/env" GOEXE="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="darwin" GOINSECURE="" GOMODCACHE="/Users/thucle/.gvm/pkgsets/go1.15.2/global/pkg/mod" GONOPROXY="github.com/liminaab/monorepo" GONOSUMDB="github.com/liminaab/monorepo" GOOS="darwin" GOPATH="/Users/thucle/.gvm/pkgsets/go1.15.2/global" GOPRIVATE="github.com/liminaab/monorepo" GOPROXY="https://proxy.golang.org,direct" GOROOT="/Users/thucle/.gvm/gos/go1.15.2" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="/Users/thucle/.gvm/gos/go1.15.2/pkg/tool/darwin_amd64" GCCGO="gccgo" AR="ar" CC="clang" CXX="clang++" CGO_ENABLED="1" GOMOD="/Users/thucle/Projects/ledongthuc/secretsmanagerui/go.mod" CGO_CFLAGS="-g -O2" CGO_CPPFLAGS="" CGO_CXXFLAGS="-g -O2" CGO_FFLAGS="-g -O2" CGO_LDFLAGS="-g -O2" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/j8/n4yx0d492pg7v2kvj7203d_c0000gn/T/go-build815956428=/tmp/go-build -gno-record-gcc-switches -fno-common" ``` ``` OS: Mac OS Catalina Terminal: Iterm 2. Build 3.3.12 ``` ``` fyne.io/fyne v1.3.3 github.com/gizak/termui/v3 v3.1.0 // indirect github.com/rivo/tview v0.0.0-20200915114512-42866ecf6ca6 // indirect ``` Expected: - Run `go run main.go`, after 5 second, Form page will switch to Table page Actual: - Form page's freezed if we don't touch on it: https://gyazo.com/beb2a6ecfb45e67550bfd5d2d5edd747 It still works if we use button to switch page. Code: ``` // Demo code for the Pages primitive. package main import ( "strings" "time" "github.com/gdamore/tcell" "github.com/rivo/tview" ) const pageCount = 5 func main() { app := tview.NewApplication() pages := tview.NewPages() /* Table */ table := tview.NewTable(). SetBorders(true) lorem := strings.Split("Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.", " ") cols, rows := 10, 40 word := 0 for r := 0; r < rows; r++ { for c := 0; c < cols; c++ { color := tcell.ColorWhite if c < 1 || r < 1 { color = tcell.ColorYellow } table.SetCell(r, c, tview.NewTableCell(lorem[word]). SetTextColor(color). SetAlign(tview.AlignCenter)) word = (word + 1) % len(lorem) } } flexTable := tview.NewFlex().SetDirection(tview.FlexRow). AddItem(tview.NewBox().SetBorder(true).SetTitle("AWS info"), 0, 1, false). AddItem(tview.NewBox().SetBorder(true).SetTitle("Searching"), 0, 2, false). AddItem(table, 0, 2, false) pages.AddPage("table", flexTable, true, false) /* Form */ form := tview.NewForm(). AddDropDown("Title", []string{"Mr.", "Ms.", "Mrs.", "Dr.", "Prof."}, 0, nil). AddInputField("First name", "", 20, nil, nil). AddInputField("Last name", "", 20, nil, nil). AddCheckbox("Age 18+", false, nil). AddPasswordField("Password", "", 10, '*', nil). AddButton("Quit", func() { pages.SwitchToPage("table") }) form.SetBorder(true).SetTitle("Enter some data").SetTitleAlign(tview.AlignLeft) flex := tview.NewFlex().SetDirection(tview.FlexRow). AddItem(tview.NewBox().SetBorder(true).SetTitle("AWS info"), 0, 1, false). AddItem(tview.NewBox().SetBorder(true).SetTitle("Searching"), 0, 2, false). AddItem(form, 0, 2, false) pages.AddPage("form", flex, true, true) /* Auto change from Form page to Table page after 5 seconds */ go func() { time.Sleep(5 * time.Second) pages.SwitchToPage("table") }() if err := app.SetRoot(pages, true).EnableMouse(true).Run(); err != nil { panic(err) } } ```
kerem closed this issue 2026-03-04 01:04:24 +03:00
Author
Owner

@jbizzle commented on GitHub (Oct 8, 2020):

Should your goroutine be calling SwitchPage from within QueueUpdate?

<!-- gh-comment-id:705643451 --> @jbizzle commented on GitHub (Oct 8, 2020): Should your goroutine be calling `SwitchPage` from within `QueueUpdate`?
Author
Owner

@ledongthuc commented on GitHub (Oct 9, 2020):

@jbizzle Thanks, it works with QueueUpdate. It's good to close this issue. Many thanks,

<!-- gh-comment-id:706023384 --> @ledongthuc commented on GitHub (Oct 9, 2020): @jbizzle Thanks, it works with `QueueUpdate`. It's good to close this issue. Many thanks,
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/tview#367
No description provided.