Creating custom event in WxPython

N

NutJob

Hello,

I'm faced with the following problem: I have a (secondary) thread that
monitors a socket for incoming message traffic using the
select.select() function.

Besides that I also have the main thread of my WxPython application. So
far so good.

Now when my socket thread detects an incoming message, I need my main
thread to interpret the message and react to it by updating the GUI.
IMO the best way to achieve this is by having my socket thread send a
custom event to my application's event loop for the main thread to
process. However, I'm at a total loss as far as creating custom events
is concerned. The WxWindows documentation isn't very helpful on this
either.
I think I need to derive my own event class from the wxEvent class, but
I have no idea HOW (i.e. what methods do I need to override, etc.) Can
anyone help me?
 
S

Sion Arrowsmith

Now when my socket thread detects an incoming message, I need my main
thread to interpret the message and react to it by updating the GUI.
IMO the best way to achieve this is by having my socket thread send a
custom event to my application's event loop for the main thread to
process. However, I'm at a total loss as far as creating custom events
is concerned. The WxWindows documentation isn't very helpful on this
either.
I think I need to derive my own event class from the wxEvent class, but
I have no idea HOW (i.e. what methods do I need to override, etc.) Can
anyone help me?

(a) Consider whether you can do what you want with CallAfter().

(b) If you do have to go with a custom event, the idiom I've got here
is:

EVT_CUSTOM_WITH_DATA_ID = wxNewId()

def EVT_CUSTOM_WITH_DATA(win, func):
win.Connect(-1, -1, EVT_CUSTOM_WITH_DATA_ID, func)

class CustomWithDataEvent(wxPyEvent):
def __init__(self, data=None):
wxPyEvent.__init__(self)
self.data = data
self.SetEventType(EVT_CUSTOM_WITH_DATA_ID)

def Clone(self):
return CustomWithDataEvent(self.data)

but do note that this is for wxPython2.4 -- amongst other differences,
EVT_CUSTOM_WITH_DATA() should be unnecessary in 2.6 (used Bind()
instead).
 
F

fraca7

(e-mail address removed) a écrit :
Now when my socket thread detects an incoming message, I need my main
thread to interpret the message and react to it by updating the GUI.
IMO the best way to achieve this is by having my socket thread send a
custom event to my application's event loop for the main thread to
process. However, I'm at a total loss as far as creating custom events
is concerned. The WxWindows documentation isn't very helpful on this
either.

I think this is what you're looking for:

# begin code

import wx

wxEVT_INVOKE = wx.NewEventType()

class InvokeEvent(wx.PyEvent):
def __init__(self, func, args, kwargs):
wx.PyEvent.__init__(self)
self.SetEventType(wxEVT_INVOKE)
self.__func = func
self.__args = args
self.__kwargs = kwargs

def invoke(self):
self.__func(*self.__args, **self.__kwargs)

class MyFrame(wx.Frame):
def __init__(self, *args, **kwargs):
wx.Frame.__init__(self, *args, **kwargs)
self.Connect(-1, -1, wxEVT_INVOKE, self.onInvoke)

def onInvoke(self, evt):
evt.invoke()

def invokeLater(self, func, *args, **kwargs):
self.GetEventHandler().AddPendingEvent(InvokeEvent(func, args,
kwargs))

# end code

This way, if frm is an instance of MyFrame, invoking
frm.invokeLater(somecallable, arguments...) will invoke 'somecallable'
with the specified arguments in the main GUI thread.

I found this idiom somewhere on the Web and can't remember where.

HTH
 
C

Chris Lambacher

You should be derriving from PyCommandEvent since only CommandEvents are set
to propegate, which is probably what you want (see the wxwidgets Event
handling overview).

In order to use Bind you will need an instance of PyEventBinder. For the
example below that would be something like:

EVT_INVOKE = PyEventBinder(wxEVT_INVOKE)

-Chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,239
Members
46,827
Latest member
DMUK_Beginner

Latest Threads

Top