[英]What event should I bind to before enabling a button in wxPython?
我有一个简单的应用程序,需要4个文件输入才能继续生成输出。 考虑btnFile1
btnFile2
btnFile3
以及btnFile4
和btnOutput
。
btnOutput
在初始化时被禁用。 btnFile1...4
都链接到四个相似但不同的方法,将它们OnBtn1..4
btnFile1...4
,它们将变量(称为file1..file4
)分配给使用wx.FileDialog
方法选择的文件。
我有一个简单的测试方法,辅助方法EnableButton()
:
if self.file1 and self.file2 and self.file3 and self.file4:
self.btnGenerate.Enable()
e.Skip()
分配所有四个变量后,调用此方法的最佳方法是什么? 可以按任意顺序单击四个按钮,因此我们不能仅将其分配给第四个按钮。
一个明显的选择是在每个OnBtn
方法中添加对EnableButton
的调用,但这是理想的解决方案吗? 如果有50个按钮怎么办?
另一个选择是向每个按钮添加一个新事件,如下所示:
for btn in (btn1, btn2, btn3, btn4):
btn.Bind(wx.EVT_BUTTON, self.EnableButton)
但是,这不适用于上面的方法,因为当单击第四个按钮时,尚未分配变量。 仅在从wx.FileDialog中选择文件后才分配它。
我确信还有第三种更理想的解决方案,我没有看到。
我将使用wx.Timer并将计时器设置为每秒触发一次。 它每秒触发一次,并调用您的EnableButton事件处理程序。 代码看起来像这样:
self.timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.EnableButton, self.timer)
self.timer.Start(1000)
在事件处理程序中,我将在if语句内添加以下内容:
self.timer.Stop()
您可能还需要添加一些逻辑以在用户关闭应用程序时停止计时器,因为如果计时器对象仍处于活动状态,则它们可能导致应用程序无法正确关闭。 您可以在此处阅读有关计时器的更多信息:
事件EVT_UPDATE_UI是一个事件处理程序,用于查看应用程序的状态并相应地更改UI元素。 您可以根据文件的状态使用它来启用或禁用按钮,这里是一个使用复选框表示文件状态的示例,仅当所有四个复选框都被选中时,该按钮才会被启用。
import wx
from wx.lib import sized_controls
class TestFrame(sized_controls.SizedFrame):
def __init__(self, *args, **kwargs):
super(TestFrame, self).__init__(*args, **kwargs)
contents_pane = self.GetContentsPane()
self.files = {}
for number in range(1, 5):
label = 'file{}'.format(number)
ctrl = wx.CheckBox(contents_pane, label=label)
self.files[label] = ctrl
btn_output = wx.Button(contents_pane, label='btn_output')
btn_output.Bind(wx.EVT_UPDATE_UI, self.btn_update)
def btn_update(self, event):
enable = all(ctrl.IsChecked() for ctrl in self.files.values())
event.Enable(enable)
app = wx.App(False)
test_frame = TestFrame(None)
test_frame.Show()
app.MainLoop()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.