Closed Thepatterraining closed 3 years ago
The code you have posted unfortunately does not compile. I tried adapting it to work but the tree wasn't visible so I could not replicate the issue.
the ChildUIDs of the tree will be triggered
You know that this is just a data lookup though right? It is not any kind of "user interaction" callback. For that you would use OnSelected
.
sorry, I revised the code and screenshots When the mouse is placed on the button, the ChildUID of the tree will be triggered
code
package main
import (
"fmt"
"os"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/layout"
"fyne.io/fyne/v2/theme"
"fyne.io/fyne/v2/widget"
)
var tree *widget.Tree
func main() {
fmt.Println("开始啦....")
myApp := app.New()
fmt.Println(myApp)
myWindow := myApp.NewWindow("Box Layout")
// filetree.DirTree(myWindow)
tree = widget.NewTree(nil, nil, nil, nil)
root := "/home/zt/go/goFile"
tree.ChildUIDs = func(uid widget.TreeNodeID) (c []widget.TreeNodeID) {
fmt.Println("tree childUIDS ...", uid)
if uid == root {
c = getFileList(uid)
} else {
c = getFileList(root)
}
return
}
tree.CreateNode = func(branch bool) (o fyne.CanvasObject) {
// label :=
var icon fyne.CanvasObject
if branch {
icon = widget.NewIcon(nil)
} else {
icon = widget.NewFileIcon(nil)
}
fmt.Println("创建node", branch)
return container.NewHBox(icon, widget.NewLabel("123"))
// return widget.NewLabel("123")
}
tree.UpdateNode = func(uid widget.TreeNodeID, branch bool, node fyne.CanvasObject) {
// lbl := node.(*widget.Label)
// lbl.(*widget.Icon).SetResource(r)
// lbl.SetText("dir or file" + uid)
c := node.(*fyne.Container)
fmt.Println("=======", uid, branch)
if branch {
var r fyne.Resource
if tree.IsBranchOpen(uid) {
// Set open folder icon
r = theme.FolderOpenIcon()
} else {
// Set folder icon
r = theme.FolderIcon()
}
c.Objects[0].(*widget.Icon).SetResource(r)
} else {
// filePath := fileTree.nodes[uid].filePath
// c.Objects[0].(*widget.FileIcon).SetURI(storage.NewFileURI(filePath))
}
c.Objects[1].(*widget.Label).SetText(uid)
}
tree.IsBranch = func(uid widget.TreeNodeID) (ok bool) {
return true
}
topBtn := widget.NewButton("show local dir", func() {
fmt.Println("clicked show btn")
})
borderLayout := layout.NewBorderLayout(topBtn, nil, nil, nil)
containerCtx := container.New(borderLayout, topBtn, tree)
myWindow.SetContent(containerCtx)
myWindow.Resize(fyne.NewSize(1000, 1000))
myWindow.ShowAndRun()
}
func getFileList(path string) (fileList []string) {
fmt.Println("path:", path)
fi2, err := os.ReadDir(path)
if err != nil {
panic("panic:fileTree:" + err.Error())
}
for _, file := range fi2 {
fileList = append(fileList, file.Name())
}
return
}
Yes, the ChildUID of the tree is just a data search, but when the mouse moves over the button, the ChildUID of the tree will be triggered, which will cause the tree to be reset. I feel that when the mouse moves into the button, nothing in the tree should be triggered. Because I want to implement an input box to enter the file directory and click the button to display the files in the file directory on the tree, but when I display it on the tree, because the mouse is on the button, the tree’s ChildUID is triggered, which causes the tree to reset back.
Thanks for explaining this - I now have the test case running
However it does not week to work well - I am getting recursive lookups in your file handling code.
which will cause the tree to be reset
This is worrying. Data access should not cause the UI to reset - I think there is an error in your code somewhere. So far I have not found a bug in Fyne. We need to look up the UID list for things like app layout so there is no guarantee that it is only called on change...
In essince your if uid == root
is a false comparison - the root UID will be "" with your setup, if you fix this then your root lookups may start working corretly.
Then if you look into your if
further you will see that both branches run the same code.
Please fix the errors in your logic and see if the errors go away. If you would like an existing file tree component consider using https://github.com/fyne-io/fyne-x/blob/master/widget/filetree.go instead.
Yes,I already try used https://github.com/fyne-io/fyne-x/blob/master/widget/filetree.go.
But it has the same problem.
These are code.I hope clicked this button show folder of /home/zt/go/goFile
on the tree.But nothing happened.
package main
import (
"fmt"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/layout"
"fyne.io/fyne/v2/storage"
"fyne.io/fyne/v2/widget"
widgetx "fyne.io/x/fyne/widget"
)
var tree *widgetx.FileTree
func main() {
fmt.Println("开始啦....")
myApp := app.New()
fmt.Println(myApp)
myWindow := myApp.NewWindow("Box Layout")
tree = widgetx.NewFileTree(storage.NewFileURI("/home/zt/go"))
topBtn := widget.NewButton("show local dir", func() {
fmt.Println("clicked show btn")
tree = widgetx.NewFileTree(storage.NewFileURI("/home/zt/go/goFile"))
})
borderLayout := layout.NewBorderLayout(topBtn, nil, nil, nil)
containerCtx := container.New(borderLayout, topBtn, tree)
myWindow.SetContent(containerCtx)
myWindow.Resize(fyne.NewSize(1000, 1000))
myWindow.ShowAndRun()
}
Yes,I already try used https://github.com/fyne-io/fyne-x/blob/master/widget/filetree.go. But it has the same problem.
Can I just re-iterate that Fyne calling 'ChildUIDs' callback is not any indication that the user has selected that item. I still don't understand what bug is being reported here.
In the code above setting a new 'FileTree' to the 'tree' variable does nothing. You have not added it to the object tree or in any way asked for it to be rendered. Consider 'Tree.SetLocation' instead.
Oh! Yes, thank you.
I re-rendered the tree variable, which solved my problem.
I thought I changed this tree variable and it will re-render automatically.
But is it too troublesome to re-render each time? Is there an automatic rendering solution?
I tried to use data binding, but the map[string]interface{}
type created by binding.NewUntypedMap()
, the function widget.NewTreeWithStrings
cannot be used. I don’t know what you said about 'Tree.SetLocation' Can this problem be solved? Where should I find it, I did not find it in the https://developer.fyne.io/api/v2.1/
document, in fyne.io/fyne/v2/widget/tree.go
It is also not found in the file.
there are codes
treeData := binding.NewUntypedMap()
treeData .SetValue("go", []string{"goFile", "gobee"})
treeDataValue , err := msb.Get()
if err != nil {
fmt.Println("error", err)
}
ms := treeDataValue.(map[string][]string)
newTree = widget.NewTreeWithStrings(ms)
I thought I changed this tree variable and it will re-render automatically.
The new item you set to the variable replaces the old one. The old one was in the visible list of objects, when you change a variable reference it does not replace the content inside the object graph. You need to tell the container to replace the old item with a new one.
But is it too troublesome to re-render each time? Is there an automatic rendering solution?
This is not a rendering problem, the issue is that your code does not tell the container to replace the content.
If you want to replace an old object with a new one regularly it may be easiest to wrap it in container.NewMax
and then you can just set the Content
whenever you want it to change.
I don’t know what you said about 'Tree.SetLocation' Can this problem be solved?
My apologies, I thought that had been implemented on the file tree widget in fyne-x, it seems we missed that. Feel free to open an issue or pull request on that repository to have it added.
I am quite confident from the questions above that the reported issue is not actually a bug. If you are looking for more general support I would recommend the #fyne channel on gophers Slack.
Describe the bug:
I have a button and a tree. When I move the mouse to the position of the button, the ChildUIDs of the tree will be triggered
To Reproduce:
Steps to reproduce the behaviour:
go run main.go
Screenshots:
As shown in the figure, placing it on any button will trigger the ChildUIDs of the tree
Example code:
Device (please complete the following information):