By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,742 Members | 1,227 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,742 IT Pros & Developers. It's quick & easy.

Creating custom event in WxPython

P: n/a
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?

Sep 1 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a
<Nu****@gmx.net> wrote:
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).

--
\S -- si***@chiark.greenend.org.uk -- http://www.chaos.org.uk/~sion/
___ | "Frankly I have no feelings towards penguins one way or the other"
\X/ | -- Arthur C. Clarke
her nu becomež se bera eadward ofdun hlęddre heafdes bęce bump bump bump
Sep 1 '05 #2

P: n/a
Nu****@gmx.net 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
Sep 1 '05 #3

P: n/a
Cool, thanks a bunch!

Sep 8 '05 #4

P: n/a
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
On Thu, Sep 01, 2005 at 04:25:05PM +0200, fraca7 wrote:
Nu****@gmx.net 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
--
http://mail.python.org/mailman/listinfo/python-list

Sep 8 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.