Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

用go程去刷下控件内容没有作用 #19

Closed
52LY opened this issue Mar 17, 2021 · 2 comments
Closed

用go程去刷下控件内容没有作用 #19

52LY opened this issue Mar 17, 2021 · 2 comments

Comments

@52LY
Copy link

52LY commented Mar 17, 2021

代码如下:

package main

import "github.com/visualfc/atk/tk"
import "strings"
import "strconv"
import "time"
import "fmt"

type Window struct { *tk.Window }


func f1(x float64) float64 {
   return x * x - x
}

func integrate_f1(a, b  float64, N int) float64 {
   // 0 23 10000000001
   var s float64 = 0
   dx := (b - a) / float64(N)

   for i:=0; i<N; i++ {
       s += f1(a + float64(i) * dx)
   }
   
   return s * dx
}

func cal(input string, resch chan string) {
    start := time.Now()

    inputnum := strings.Split(input," ")
    a,_ := strconv.ParseFloat(inputnum[0], 64)
    b,_ := strconv.ParseFloat(inputnum[1], 64)
    N,_ := strconv.Atoi(inputnum[2])
    res := integrate_f1(a, b, N)

    end := time.Now()
    
    delta := end.Sub(start)
    
    resch <- fmt.Sprintf("计算结果: \nres is %v \ntime: %s", res, delta)
    
}

func NewWindow() *Window {
    
    s1 := make(chan string)
    
    mw := &Window{}
    mw.Window = tk.RootWindow()
    
    labelf := tk.NewLabel(mw, "计算阻塞")
    entryf := tk.NewEntry(mw,)
    labels := tk.NewLabel(mw, "计算结果: ")
    btn1 := tk.NewButton(mw,"开始计算",tk.WidgetAttrInitUseTheme(true))
    btn2 := tk.NewButton(mw,"退出",tk.WidgetAttrInitUseTheme(true))

    btn1.SetTakeFocus(false)
    btn2.SetTakeFocus(false)

    // go运行耗时函数,然后go刷新label控件内容,但是内容没有刷新
    // labels.SetText(<-s1)这样的话可以刷新,但是界面会阻塞
    // go func() { fmt.Println(<-s1) }() 这样打印结果也没问题,界面不会阻塞
    btn1.OnCommand(func() { 
        go cal(entryf.Text(),s1)
        go func() { labels.SetText(<-s1) }()
    })
    
    btn2.OnCommand(func() { tk.Quit() })

    vbox := tk.NewVPackLayout(mw)
    vbox.SetPaddingN(5, 5)
    vbox.AddWidgetEx(labelf, 0, false, 6)
    vbox.AddWidgetEx(entryf, 0, false, 6)
    vbox.AddWidgetEx(labels, 0, false, 6)
    vbox.AddWidgetEx(btn1, 0, false, 6)
    vbox.AddWidgetEx(btn2, 0, false, 6)

    return mw
}

func main() {
    win := func() {
        mw := NewWindow()
        mw.SetTitle("阻塞窗口例子")
        mw.ResizeN(600, 600)
        mw.Center(nil)
        mw.ShowNormal()
    }
    
    tk.MainLoop(win)
}
@visualfc
Copy link
Owner

visualfc commented Mar 18, 2021

一个原则是永远不要在 go func() 中 直接对 UI 进行读和写,需要时可以使用 tk.Async 函数

btn1.OnCommand(func() {
	in := entryf.Text() 
       // 先从 ui 中获取值,再运行 go func
	go cal(in, s1)
	go func() {
		out := <-s1
                // 先获取值,再通过 Async 对 ui 读写
		tk.Async(func() {
			labels.SetText(out) 
		})
	}()
})

@52LY
Copy link
Author

52LY commented Mar 18, 2021

感谢

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants