【问题标题】:WxPython - trigger checkbox event while setting its value in the codeWxPython - 在代码中设置其值时触发复选框事件
【发布时间】:2012-04-03 16:12:50
【问题描述】:

考虑以下代码:

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 个复选框绑定在一起,所以 cb2 会在 cb1 时被检查,cb3cb2 时会被检查。但是,当我在OnCb1 例程中设置cb2 的值时,不会触发cb2 复选框事件,并且cb3 复选框保持未选中状态。所以我想找到一种方法以某种方式手动触发cb2 事件,以便在仅检查cb1 时一次检查所有 3 个框。如果有人给我提示,我将不胜感激。

【问题讨论】:

    标签: python event-handling wxpython


    【解决方案1】:

    像这样使用 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)
    

    【讨论】:

    • 是的,我终于用类似的方法解决了
    【解决方案2】:

    我不能直接采用 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,但这对我有用。

    【讨论】:

      【解决方案3】:

      我没有使用 wxPython 的经验,所以我不能给你一个具体的例子,但我知道以编程方式设置值不会触发小部件的命令事件。我的假设是,您必须在设置 cb2 的值后手动发布该事件。您可以在这里查看类似的问题:wxPython: Calling an event manually

      我可能建议将 wx.CheckBox 子类化并创建一个SetValueWithEvent() 或类似的方法,该方法将调用 SetValue 并发布一个wx. EVT_CHECKBOX 事件。

      PyQt 也有类似的情况,在以编程方式在小部件上设置值时可能会发出信号,也可能不会发出信号。他们有时会给你一个以上的信号,你可以听听以适应任何一种方式。不幸的是,仅基于我对 wxPython 示例的有限接触,我认为它更加原始,并且没有那么 Pythonic。所以你似乎不得不更频繁地自己做事。

      【讨论】:

      • 感谢您的链接,但不幸的是我无法发布带有 cb2 id 的 EVT_CHECKBOX 事件。显然,发布了一些事件,但没有使用 OnCb2 例程进行处理。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-02-02
      • 1970-01-01
      • 2010-10-30
      • 1970-01-01
      • 2015-08-09
      • 1970-01-01
      • 2019-04-13
      相关资源
      最近更新 更多