如何在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
相关产品推荐
相关产品推荐

