【问题标题】:How to programmatically generate an event in wxPython如何以编程方式在 wxPython 中生成事件
【发布时间】:2014-08-14 03:49:17
【问题描述】:

我有一个 wxPython gui,我想以编程方式生成一个事件。

我试过这样的语法:

e = wx.Event.__init__(grid, eventType=wx.EVT_LEFT_DOWN)

导致:

TypeError: unbound method __init__() must be called with Event instance as first argument (got Grid instance instead)

或:

 e = wx.CommandEvent(commandType=wx.EVT_BUTTON)

TypeError: in method 'new_CommandEvent', expected argument 1 of type 'wxEventType'

所以问题很简单,我需要使用什么确切的文字语法来创建事件对象?或者,有人能指出我理解事件的好资源吗?我不知道我是否只是在我的理解中遗漏了一些简单的东西。我还没有在网上找到这个问题的直接答案。我检查了这个问题:Generate a custom CommandEvent in wxPython,但我不想制作自定义事件。

提前致谢!

【问题讨论】:

    标签: python datagrid wxpython


    【解决方案1】:

    你会想使用wx.PostEvent

    以编程方式生成事件:

    wx.PostEvent(self.GetEventHandler(), wx.PyCommandEvent(wx.EVT_BUTTON.typeId, self.GetId()))
    

    如果您想发布wx.EVT_BUTTON 事件。将其设为PyCommandEvent 意味着它将向上传播;其他事件类型默认不传播。

    wx.PostEvent()的一般形式:http://www.wxpython.org/docs/api/wx-module.html#PostEvent

    这是一个小示例代码:

    import wx
    
    class MyFrame ( wx.Frame ):
    
        def __init__( self, parent ):
            wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = u"Test", pos = wx.DefaultPosition, size = wx.Size( 200,200 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
    
            sizer_inside = wx.BoxSizer( wx.VERTICAL )
    
            # Adding a button and a textCtrl widget
            self.button = wx.Button( self, wx.ID_ANY, u"Click Me", wx.DefaultPosition, wx.DefaultSize, 0 )
            sizer_inside.Add( self.button, 0, wx.ALIGN_CENTER|wx.ALL, 5 )
            self.textCtrl = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, wx.TE_NO_VSCROLL )
            sizer_inside.Add( self.textCtrl, 0, wx.ALIGN_CENTER|wx.ALL, 5 )
    
            self.SetSizer( sizer_inside )
            self.Layout()
            self.Centre( wx.BOTH )
            self.Show()
    
            self.counter = 0
    
            # Binding Events
            self.Bind( wx.EVT_BUTTON, self.on_click )
            self.Bind( wx.EVT_CHOICE, self.test_dummy)
    
        #Event handlers
        def on_click( self, event ):
            self.counter += 1
            wx.PostEvent(self.GetEventHandler(), wx.PyCommandEvent(wx.EVT_CHOICE.typeId, self.GetId()))
    
        def test_dummy(self, event):
            self.counter += 1
            self.textCtrl.SetValue(str(self.counter))
    
    if __name__ == "__main__":
        app = wx.App(False)
        MyFrame(None)
        app.MainLoop()
    

    如果你运行它,请注意textCtrl 在点击按钮后会显示2。第一个事件处理程序手动触发由test_dummy 处理的第二个事件。

    【讨论】:

    • 谢谢.. 我不明白的关键信息是 wx.PyCommandEvent 需要一个 integer。另外,感谢其他回答者指出 wx.wxEVT_* 语法。
    【解决方案2】:

    我认为你最好使用 win32gui.PostMessage()。

    这会对你有所帮助。

    http://markmail.org/message/epiclzlaph44f3kk

    【讨论】:

    • 您应该将相关代码添加到您的答案中,以防该链接失效。此外,我们不确定 OP 使用的是 Windows,或者他/她是否可以接受仅 Windows 的解决方案。
    • 谢谢,这救了我。我试图在 Windows 下调用 WxPython 上的 Next 按钮。如果我理解正确,因为这是一个 Windows 类(而不是 Python 类),所以我不能使用 Python 事件。因此,我不得不调用 windows 事件。当我确实尝试使用 pythonic 事件时,我的向导将结束而无需浏览页面,就像我按下“完成”按钮一样,即使它在页面上不可见。也许另一种策略是从 windows 向导类切换到 pythonic 向导类,但我没有尝试。
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      谢谢。 @i5on9i 评论救了我。

      我试图在 Windows 下调用 WxPython 上的 Next 按钮。

      当我尝试使用 pythonic 事件时,我的向导将直接结束而无需浏览页面,就好像我按下了“完成”按钮,即使它在页面上不可见。

      如果我理解正确,因为这是一个 Windows 类(而不是 pythonic 类),我不能使用 pythonic 事件。因此我不得不调用 windows 事件。

      也许另一种策略是从 windows 向导类切换到 pythonic 向导类,但我没有尝试。

      顺便说一句,我最终发送的消息是:

      win32gui.PostMessage(wizard.GetHandle(),0x0111,wx.ID_FORWARD,self.wizard.FindWindowById(wx.ID_FORWARD).GetHandle())
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-07-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-12
        • 2011-02-02
        • 2014-08-08
        相关资源
        最近更新 更多