第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

如何使用 fyne 避免 GUI 應(yīng)用程序中的循環(huán)依賴?

如何使用 fyne 避免 GUI 應(yīng)用程序中的循環(huán)依賴?

Go
肥皂起泡泡 2022-11-23 16:23:20
我想將 GUI 添加到我用 Go 編寫的命令行應(yīng)用程序,但我遇到了 fyne 和循環(huán)依賴性問題??紤]這個(gè)簡單的例子來說明我面臨的問題:假設(shè)一個(gè)按鈕在我的模型類上觸發(fā)了一個(gè)耗時(shí)的方法(比如獲取數(shù)據(jù)等)并且我希望視圖在任務(wù)完成時(shí)更新。我首先實(shí)現(xiàn)了一個(gè)非常幼稚且完全不解耦的解決方案,這顯然會(huì)遇到 go 編譯器引發(fā)的循環(huán)依賴錯(cuò)誤。考慮以下代碼:主程序package mainimport (    "my-gui/gui")func main() {    gui.Init()}gui/gui.gopackage guiimport (    "my-gui/model"    //[...] fyne imports)var counterLabel *widget.Labelfunc Init() {    myApp := app.New()    myWindow := myApp.NewWindow("Test")    counterLabel = widget.NewLabel("0")    counterButton := widget.NewButton("Increment", func() {        go model.DoTimeConsumingStuff()    })    content := container.NewVBox(counterLabel, counterButton)    myWindow.SetContent(content)    myWindow.ShowAndRun()}func UpdateCounterLabel(value int) {    if counterLabel != nil {        counterLabel.SetText(strconv.Itoa(value))    }}模型/模型.gopackage modelimport (    "my-gui/gui" // <-- this dependency is where it obviously hits the fan    //[...])var counter = 0func DoTimeConsumingStuff() {    time.Sleep(1 * time.Second)        counter++    fmt.Println("Counter: " + strconv.Itoa(counter))    gui.UpdateCounterLabel(counter)}所以我想知道如何正確解耦這個(gè)簡單的應(yīng)用程序以使其正常工作。我在想什么:使用 fyne 數(shù)據(jù)綁定:這應(yīng)該適用于簡單的東西,例如上面示例中的標(biāo)簽文本。但是,如果我必須根據(jù)模型的狀態(tài)以非常自定義的方式更新更多內(nèi)容怎么辦?假設(shè)我必須根據(jù)模型的條件更新按鈕的啟用狀態(tài)。這怎么能綁定到數(shù)據(jù)呢?這可能嗎?使用標(biāo)準(zhǔn) MVC 設(shè)計(jì)模式中的接口:我也嘗試過這個(gè),但無法真正理解它。我創(chuàng)建了一個(gè)單獨(dú)的模塊,它將提供一個(gè)接口,然后可以由模型類導(dǎo)入。然后我會(huì)注冊一個(gè)視圖(隱式地)實(shí)現(xiàn)與模型的接口。但我無法讓它工作。我認(rèn)為此時(shí)我對 go 接口的理解還不夠。短輪詢模型:這只是meh,當(dāng)然不是 Go 和/或 fyne 的開發(fā)人員的意圖:-)任何人都可以指出這個(gè)問題的慣用解決方案嗎?我可能在這里遺漏了一些非常非?;镜臇|西......
查看完整描述

1 回答

?
蝴蝶不菲

TA貢獻(xiàn)1810條經(jīng)驗(yàn) 獲得超4個(gè)贊

返回值

你可以返回值。


func DoTimeConsumingStuff() int {

    time.Sleep(1 * time.Second)

    counter++

    return counter

}

然后在單擊按鈕時(shí)生成一個(gè)匿名 goroutine,以免阻塞 UI。


counterButton := widget.NewButton("Increment", func() {

    go func() {

        counter := model.DoTimeConsumingStuff(counterChan)

        UpdateCounterLabel(counter)

    }()      

})

打回來

您可以將該UpdateCounterLabel函數(shù)傳遞給您的模型函數(shù),也就是回調(diào)。


func DoTimeConsumingStuff(callback func(int)) {

    time.Sleep(1 * time.Second)

    counter++

    callback(counter)

}

counterButton := widget.NewButton("Increment", func() {

    go model.DoTimeConsumingStuff(UpdateCounterLabel)

})

渠道

也許您還可以將一個(gè)通道傳遞給您的模型函數(shù)。但是使用上述方法,這似乎不是必需的。潛在地,如果你有不止一個(gè)反價(jià)值。


func DoTimeConsumingStuff(counterChan chan int) {

    for i := 0; i < 10; i++ {

        time.Sleep(1 * time.Second)

        counter++

        counterChan <- counter

    }

    close(counterChan)

}

然后在 GUI 中,您可以從通道接收,再次在 goroutine 中,以免阻塞 UI。


counterButton := widget.NewButton("Increment", func() {

    go func() {

        counterChan := make(chan int)

        go model.DoTimeConsumingStuff(counterChan)

        for counter := range counterChan {

            UpdateCounterLabel(counter)

        }

    }()      

})

當(dāng)然,您也可以再次使用在每次迭代時(shí)調(diào)用的回調(diào)。


查看完整回答
反對 回復(fù) 2022-11-23
  • 1 回答
  • 0 關(guān)注
  • 184 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號