[GH-ISSUE #203] [Question] How to redraw the element changes in treeview? #158

Closed
opened 2026-03-04 01:02:29 +03:00 by kerem · 1 comment
Owner

Originally created by @thedevsaddam on GitHub (Dec 9, 2018).
Original GitHub issue: https://github.com/rivo/tview/issues/203

I want to redraw the tree after some changes in an element,

Code:

// Demo code for the TreeView primitive.
package main

import (
	"time"

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

var names = []string{"tom", "jhon", "jane", "jerry"}

// Show a navigable tree view of the current directory.
func main() {
	root := tview.NewTreeNode("Names").
		SetColor(tcell.ColorRed).SetSelectable(false)
	tree := tview.NewTreeView().
		SetRoot(root).
		SetCurrentNode(root)

	add := func(target *tview.TreeNode) {
		for _, name := range names {
			node := tview.NewTreeNode(name).SetReference(name)
			target.AddChild(node)
		}
	}
	add(root)

	tree.SetSelectedFunc(func(node *tview.TreeNode) {
		names[0] = "Doraemon" // need to redraw the tree with element modification
	})

	app := tview.NewApplication()

	go func() {
		for i := 0; i < 1000; i++ {
			app.ForceDraw()
			time.Sleep(500 * time.Millisecond)
		}
	}()

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

Originally created by @thedevsaddam on GitHub (Dec 9, 2018). Original GitHub issue: https://github.com/rivo/tview/issues/203 I want to redraw the tree after some changes in an element, Code: ```go // Demo code for the TreeView primitive. package main import ( "time" "github.com/gdamore/tcell" "github.com/rivo/tview" ) var names = []string{"tom", "jhon", "jane", "jerry"} // Show a navigable tree view of the current directory. func main() { root := tview.NewTreeNode("Names"). SetColor(tcell.ColorRed).SetSelectable(false) tree := tview.NewTreeView(). SetRoot(root). SetCurrentNode(root) add := func(target *tview.TreeNode) { for _, name := range names { node := tview.NewTreeNode(name).SetReference(name) target.AddChild(node) } } add(root) tree.SetSelectedFunc(func(node *tview.TreeNode) { names[0] = "Doraemon" // need to redraw the tree with element modification }) app := tview.NewApplication() go func() { for i := 0; i < 1000; i++ { app.ForceDraw() time.Sleep(500 * time.Millisecond) } }() if err := app.SetRoot(tree, true).Run(); err != nil { panic(err) } } ```
kerem closed this issue 2026-03-04 01:02:29 +03:00
Author
Owner

@rivo commented on GitHub (Dec 14, 2018):

First of all, please never call app.ForceDraw() from a goroutine as it may cause race conditions. As mentioned in the function comments, you should probably never need to call this function at all.

It is also not needed to periodically redraw the screen. Application.Draw() is called automatically in response to events such as the "selected" event.

In your SetSelectedFunc() callback, you only modify your string slice. That has no effect on the tree view. If you want changes to the tree view, you'll also need to modify a tree node. Here's a version that may do what you need:

// Demo code for the TreeView primitive.
package main

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

var names = []string{"tom", "jhon", "jane", "jerry"}

// Show a navigable tree view of the current directory.
func main() {
	root := tview.NewTreeNode("Names").
		SetColor(tcell.ColorRed).SetSelectable(false)
	tree := tview.NewTreeView().
		SetRoot(root).
		SetCurrentNode(root)

	add := func(target *tview.TreeNode) {
		for index, name := range names {
			node := tview.NewTreeNode(name).SetReference(index)
			target.AddChild(node)
		}
	}
	add(root)

	tree.SetSelectedFunc(func(node *tview.TreeNode) {
		node.SetText("Doraemon") // Change the tree node's text.
		index := node.GetReference().(int)
		names[index] = "Doraemon" // Also change the text in the name slice.
	})

	app := tview.NewApplication()

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

Let me know if this solves your problem.

<!-- gh-comment-id:447391823 --> @rivo commented on GitHub (Dec 14, 2018): First of all, please never call `app.ForceDraw()` from a goroutine as it may cause race conditions. As mentioned in the function comments, you should probably never need to call this function at all. It is also not needed to periodically redraw the screen. `Application.Draw()` is called automatically in response to events such as the "selected" event. In your `SetSelectedFunc()` callback, you only modify your string slice. That has no effect on the tree view. If you want changes to the tree view, you'll also need to modify a tree node. Here's a version that may do what you need: ```go // Demo code for the TreeView primitive. package main import ( "github.com/gdamore/tcell" "github.com/rivo/tview" ) var names = []string{"tom", "jhon", "jane", "jerry"} // Show a navigable tree view of the current directory. func main() { root := tview.NewTreeNode("Names"). SetColor(tcell.ColorRed).SetSelectable(false) tree := tview.NewTreeView(). SetRoot(root). SetCurrentNode(root) add := func(target *tview.TreeNode) { for index, name := range names { node := tview.NewTreeNode(name).SetReference(index) target.AddChild(node) } } add(root) tree.SetSelectedFunc(func(node *tview.TreeNode) { node.SetText("Doraemon") // Change the tree node's text. index := node.GetReference().(int) names[index] = "Doraemon" // Also change the text in the name slice. }) app := tview.NewApplication() if err := app.SetRoot(tree, true).Run(); err != nil { panic(err) } } ``` Let me know if this solves your problem.
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#158
No description provided.