Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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:

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

or:

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

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

So question is simply, what is the exact, literal syntax that I need to use to create an event object? Or, can someone point me to a good resource for making sense of events? I don't know if I'm just missing something simple in my understanding. I haven't been able to find a direct answer to this question yet online. I checked out this question: Generate a custom CommandEvent in wxPython , but I don't want to make a custom event.

Thanks in advance!

like image 502
J Jones Avatar asked May 21 '26 22:05

J Jones


2 Answers

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

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()

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.

like image 159
user2963623 Avatar answered May 24 '26 12:05

user2963623


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

This would help you.

http://markmail.org/message/epiclzlaph44f3kk

like image 34
i5on9i Avatar answered May 24 '26 12:05

i5on9i



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!