Skip to content Skip to sidebar Skip to footer

How To Programmatically Generate An Event In Wxpython

I have a wxPython gui and I want to programmatically generate an event. I've tried a syntax like this: e = wx.Event.__init__(grid, eventType=wx.EVT_LEFT_DOWN) which results in:

Solution 1:

You would want to use wx.PostEvent

To programatically generate an event:

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

if you want to post a wx.EVT_BUTTON event. Making it a PyCommandEvent means it will propagate upwards; other event types don't propagate by default.

The general form of wx.PostEvent(): http://www.wxpython.org/docs/api/wx-module.html#PostEvent

Here's a small example code:

import wx

classMyFrame ( 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 handlersdefon_click( self, event ):
        self.counter += 1
        wx.PostEvent(self.GetEventHandler(), wx.PyCommandEvent(wx.EVT_CHOICE.typeId, self.GetId()))

    deftest_dummy(self, event):
        self.counter += 1
        self.textCtrl.SetValue(str(self.counter))

if __name__ == "__main__":
    app = wx.App(False)
    MyFrame(None)
    app.MainLoop()

If you run this, notice that the textCtrl will display 2 after clicking the button. The first event handler manually fires the second event which is handled by test_dummy.

Solution 2:

I think you'd better using win32gui.PostMessage().

This would help you.

http://markmail.org/message/epiclzlaph44f3kk

Solution 3:

Use wx.PostEvent... like so:

classlauncherWindow(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 productsfor 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...defonProductSelection(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)

Solution 4:

thanks. @i5on9i comment saved me.

I was trying to call the Next button on WxPython under Windows.

When I did try to use a pythonic event my wizard would just end without going through the pages as if I pressed the "Finish" button even though it was not visible on the page.

If I understand correctly, since this is a Windows class (and not a pythonic class) I could not use a pythonic event. I therefore had to call the windows event.

Perhaps a different strategy would have been to switch from a windows Wizard class to a pythonic wizard class but I didn't try it.

BTW the message I ended up sending was:

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

Post a Comment for "How To Programmatically Generate An Event In Wxpython"