WxPython-在代码中设置其值时触发复选框事件
考虑以下代码:WxPython-在代码中设置其值时触发复选框事件,python,event-handling,wxpython,Python,Event Handling,Wxpython,考虑以下代码: import wx class MyFrame(wx.Frame): def __init__(self, *args, **kwds): wx.Frame.__init__(self, *args, **kwds) self.cb1 = wx.CheckBox(self, -1, "CheckBox 1") self.cb2 = wx.CheckBox(self, -1, "CheckBox 2") se
import wx
class MyFrame(wx.Frame):
def __init__(self, *args, **kwds):
wx.Frame.__init__(self, *args, **kwds)
self.cb1 = wx.CheckBox(self, -1, "CheckBox 1")
self.cb2 = wx.CheckBox(self, -1, "CheckBox 2")
self.cb3 = wx.CheckBox(self, -1, "CheckBox 3")
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.cb1, 0, wx.ADJUST_MINSIZE, 0)
sizer.Add(self.cb2, 0, wx.ADJUST_MINSIZE, 0)
sizer.Add(self.cb3, 0, wx.ADJUST_MINSIZE, 0)
self.SetSizer(sizer)
self.Layout()
self.Bind(wx.EVT_CHECKBOX, self.OnCb1, self.cb1)
self.Bind(wx.EVT_CHECKBOX, self.OnCb2, self.cb2)
def OnCb1(self, evt):
self.cb2.SetValue(evt.IsChecked())
def OnCb2(self, evt):
self.cb3.SetValue(evt.IsChecked())
if __name__ == "__main__":
app = wx.PySimpleApp(0)
frame = MyFrame(None, -1, "")
app.SetTopWindow(frame)
frame.Show()
app.MainLoop()
这里我有3个复选框绑定在一起,因此当
cb1
执行时,cb2
将被选中,而cb3
执行时,cb2
将被选中。但是,当我在OnCb1
例程中设置cb2
的值时,cb2
复选框事件不会触发,cb3
复选框保持未选中状态。因此,我想找到一种方法,手动触发cb2
事件,以便在仅选中cb1
时同时选中所有3个框。如果有人给我一个提示,我将不胜感激。我对wxPython没有经验,所以我不能给你一个具体的例子,但我知道以编程方式设置值不会触发小部件的命令事件。我的假设是,在设置cb2的值后,您必须手动发布cb2的事件。您可以在此处查看类似的问题:
我建议将wx.CheckBox子类化,创建一个SetValueWithEvent()
或类似的方法,该方法将调用SetValue,并发布一个wx。EVT_复选框
事件
PyQt具有类似的情况,即当以编程方式在小部件上设置值时,可能会发出信号,也可能不会发出信号。他们有时会给你一个以上的信号,你可以听,以适应任何一种方式。不幸的是,仅根据我对wxPython示例的有限接触,我认为它要原始得多,而且有点不太像Python。所以你似乎不得不自己多做一些事情。使用wx.PostEvent。。。像这样:
class launcherWindow(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, parent=None, title='New Window')
#now add the main body, start with a panel
panel = wx.Panel(self)
#instantiate a new dropdown
self.productDropDown = wx.ComboBox(panel, size=wx.DefaultSize, style = wx.CB_READONLY)
#get the products and product subtypes
self.productDict = self.getProductsAndSubtypes()
#setup subtypes first, just in case, since onProductSelection will reference this
self.productSubtypeDropDown = wx.ComboBox(panel, size=wx.DefaultSize, style = wx.CB_READONLY)
#add products
for product in self.productDict.keys():
self.productDropDown.Append(product)
#bind selection event
self.productDropDown.Bind(wx.EVT_COMBOBOX, self.onProductSelection)
#set default selection
self.productDropDown.SetSelection(0)
#pretend that we clicked the product selection, so it's event gets called
wx.PostEvent(self.productDropDown, wx.CommandEvent(wx.wxEVT_COMMAND_COMBOBOX_SELECTED))
#now add the dropdown to a sizer, set the sizer for the panel, fit the panel, etc...
def onProductSelection(self, event):
productSelected = self.productDropDown.GetStringSelection()
productSubtypes = self.productDict[productSelected]
#clear any existing product subtypes, since each product may have different ones
self.productSubtypeDropDown.Clear()
for productSubtype in productSubtypes:
self.productSubtypeDropDown.Append(productSubtype)
#select the first item by default
self.productSubtypeDropDown.SetSelection(0)
我不能直接采用nmz787的代码,不得不稍微修改一下,但我最终还是让它为我工作了
- 更改复选框的状态并
- 让复选框接收事件
def toggleCheckBox(cb):
evt = wx.CommandEvent(commandType=wx.EVT_CHECKBOX.typeId)
evt.SetEventObject(cb)
cb.SetValue( not cb.GetValue())
wx.PostEvent(cb, evt)
我不知道CommandEvent构造函数为什么需要一个关键字,或者是否有一种更合理、更健壮的方法来获取所需的typeId,但这对我来说很有效。感谢链接,但不幸的是,我无法发布带有cb2 id的EVT_复选框事件。显然,某些事件已发布,但未使用OnCb2例程处理。是的,我最终以类似的方式解决了这个问题