You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Fyne中条件性显示/隐藏工具栏按钮?

解决Fyne工具栏录制/停止按钮切换显示问题

你的核心问题在于两点:一是Fyne的Toolbar不会自动感知子项可见性变化,需要手动触发布局刷新;二是后台goroutine中直接修改UI违反了Fyne的UI线程安全规则,必须通过主线程更新队列执行UI操作。

以下是修正后的完整代码:

import (
    "fyne.io/fyne/v2"
    "fyne.io/fyne/v2/theme"
    "fyne.io/fyne/v2/widget"
    "sync"
)

var (
    recording      bool
    stopRecording  chan struct{}
    recordWg       sync.WaitGroup
)

func setupRecordToolbar() *widget.Toolbar {
    var startRecording, stopRecordingFunc func()

    recordButton := widget.NewToolbarAction(theme.MediaRecordIcon(), nil)
    stopButton := widget.NewToolbarAction(theme.MediaStopIcon(), nil)

    toolbar := widget.NewToolbar(recordButton, stopButton)

    startRecording = func() {
        if !recording {
            recording = true
            stopRecording = make(chan struct{})
            recordWg.Add(1)
            
            go func() {
                recordAudio("output.wav", stopRecording, &recordWg)
                // 通过主线程队列更新UI
                fyne.CurrentApp().QueueUpdate(func() {
                    recording = false
                    recordButton.ToolbarObject().Show()
                    stopButton.ToolbarObject().Hide()
                    toolbar.Refresh() // 强制刷新工具栏布局
                })
            }()
            
            // 主线程中修改按钮可见性并刷新
            recordButton.ToolbarObject().Hide()
            stopButton.ToolbarObject().Show()
            toolbar.Refresh()
        }
    }

    stopRecordingFunc = func() {
        if recording {
            close(stopRecording)
            recordWg.Wait()
            
            // 修改可见性并刷新
            recording = false
            recordButton.ToolbarObject().Show()
            stopButton.ToolbarObject().Hide()
            toolbar.Refresh()
        }
    }

    recordButton.OnActivated = startRecording
    stopButton.OnActivated = stopRecordingFunc

    // 初始化时隐藏停止按钮并刷新
    stopButton.ToolbarObject().Hide()
    toolbar.Refresh()

    return toolbar
}

// 假设你的recordAudio函数实现如下
func recordAudio(outputPath string, stop chan struct{}, wg *sync.WaitGroup) {
    defer wg.Done()
    // 你的音频录制逻辑
}

关键修正点:

  • UI线程安全:后台goroutine中的UI操作必须通过fyne.CurrentApp().QueueUpdate()包裹,确保在主线程执行,避免UI更新失效或异常。
  • 强制刷新布局:每次修改按钮可见性后,调用toolbar.Refresh()触发Toolbar重新计算布局,让可见性变化生效。
  • 初始化修正:创建Toolbar后再绑定按钮的激活事件,确保逻辑关联正确,同时初始化隐藏停止按钮后立即刷新。

内容的提问来源于stack exchange,提问作者jbrown

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 18:17:26