Search code examples
gofyne

main () not waiting for update of file dialog in golang using fyne for file dialog


I would like to use a file dialog to select a directory for further use in Go. To select the directory i am using a Fyne file dialog as the rest of the application uses Fyne as well. I managed to create a simple test application:

package main

import (
    "fmt"

    "fyne.io/fyne/v2"
    "fyne.io/fyne/v2/app"
    "fyne.io/fyne/v2/container"
    "fyne.io/fyne/v2/dialog"
    "fyne.io/fyne/v2/widget"
)

var save_dir string = "NoPathYet!"

func chooseDirectory(w fyne.Window) string {
    dialog.ShowFolderOpen(func(dir fyne.ListableURI, err error) {
        if err != nil {
            dialog.ShowError(err, w)
            return
        }
        if dir != nil {

            fmt.Println(dir.Path())
            save_dir = dir.Path() // here value of save_dir shall be updated!

        }
        fmt.Println(save_dir)

    }, w)
    return save_dir
}

func main() {
    a := app.New()
    w := a.NewWindow("FileDialogTest")

    hello := widget.NewLabel("Hello Fyne!")
    w.SetContent(container.NewVBox(
        hello,
        widget.NewButton("Go Get Directory!", func() {
            hello.SetText(chooseDirectory(w)) // Text of hello updated by return value
        }),
    ))
    w.Resize(fyne.NewSize(500, 500))
    w.ShowAndRun()
}

It does not work properly, the label hello is updated prior to the return of the value, somehow...

When the button "Go Get Directory!" is clicked the function chooseDirectory should called and the return value should be set as text in the hello-Label.

I am a Golang-Newbie, so my question may be silly for more experienced Go programmers. In any case I would appreciate help!

Thanks in advance,

Vinz


Solution

  • Remember the point of callback function is not to wait. In your code the chooseDirectory(w) is always returned before the user selects any folder. So, you should directly update hello label text within the callback of ShowFolderOpen.

    Here is working code as expected.

    package main
    
    import (
        "fmt"
    
        "fyne.io/fyne/v2"
        "fyne.io/fyne/v2/app"
        "fyne.io/fyne/v2/container"
        "fyne.io/fyne/v2/dialog"
        "fyne.io/fyne/v2/widget"
    )
    
    func chooseDirectory(w fyne.Window, h *widget.Label) {
        dialog.ShowFolderOpen(func(dir fyne.ListableURI, err error) {
            save_dir := "NoPathYet!"
            if err != nil {
                dialog.ShowError(err, w)
                return
            }
            if dir != nil {
                fmt.Println(dir.Path())
                save_dir = dir.Path() // here value of save_dir shall be updated!
            }
            fmt.Println(save_dir)
            h.SetText(save_dir)
        }, w)
    }
    
    func main() {
        a := app.New()
        w := a.NewWindow("FileDialogTest")
    
        hello := widget.NewLabel("Hello Fyne!")
        w.SetContent(container.NewVBox(
            hello,
            widget.NewButton("Go Get Directory!", func() {
                chooseDirectory(w, hello) // Text of hello updated by return value
            }),
        ))
        w.Resize(fyne.NewSize(500, 500))
        w.ShowAndRun()
    }