Problem with custom events in wxpython

J

Jimmy

hi, all

I'm having a problem with creating custom events in wxpython.

I have a class A handling some data processing work and another class
B of GUI matter. I need GUI to display information when data in A is
updated.
I know cutom events in wxpython may work. But I found no material
paricularly
helpful :(

can anyone write me some demo code to show how to do this or ant
reference to
materials? thanks
 
F

Frank Niessink

Hi Jimmy,

2008/5/11 Jimmy said:
hi, all

I'm having a problem with creating custom events in wxpython.

I have a class A handling some data processing work and another class
B of GUI matter. I need GUI to display information when data in A is
updated.
I know cutom events in wxpython may work.

You may want to look at the pubsub module. Available as wx.lib.pubsub
in wxPython: http://www.wxpython.org/docs/api/wx.lib.pubsub-module.html,
and also available separately on PyPI:
http://pypi.python.org/pypi/PyPubSub/

Cheers, Frank
 
7

7stud

hi, all

I'm having a problem with creating custom events in wxpython.

I have a class A handling some data processing work and another class
B of GUI matter. I need GUI to display information when data in A is
updated.
I know cutom events in wxpython may work. But I found no material
paricularly
helpful :(

can anyone write me some demo code to show how to do this ...


This example works for me:


import wx

class MyCustomEvent(wx.PyCommandEvent): #or wx.PyEvent
def __init__(self, event_type, id):
wx.PyCommandEvent.__init__(self, event_type, id)

class A(object): #Data Processing class
def __init__(self, widget_to_update):
self.widget_to_update = widget_to_update

#create the custom event:
self.my_event_type = wx.NewEventType()
self.EVT_MY_CUSTOM_EVENT =
wx.PyEventBinder(self.my_event_type, 1)
#Note: you need to make EVT_MY_CUSTOM_EVENT persist so that you
#can refer to it in a later call to Bind()

def process_data(self): #create thread here
finished = True

if finished:
self.update_gui()


def update_gui(self):
#create a custom event object and enter it in the event queue:
my_evt_obj = MyCustomEvent(self.my_event_type,
self.widget_to_update.GetId() )

self.widget_to_update.GetEventHandler().ProcessEvent(my_evt_obj)


class B(object): #Gui class
def __init__(self):
frame = wx.Frame(None, -1, "My Window")

panel = wx.Panel(frame, -1)
button = wx.Button(panel, -1, "Start Data Processing",
pos=(100, 10))
button.Bind(wx.EVT_BUTTON, self.onclick)

self.text_ctrl = wx.TextCtrl(panel, -1, "Hello World",
pos=(100, 50), size=(200, 20))

self.a = A(self.text_ctrl)
frame.Bind(self.a.EVT_MY_CUSTOM_EVENT,
self.on_my_custom_event)

frame.Show()

def onclick(self, event):
self.a.process_data()

def on_my_custom_event(self, event):
self.text_ctrl.SetValue("Finished Processing Data")


app = wx.PySimpleApp(redirect=False)
b = B()
app.MainLoop()




However, I couldn't get similar code to work when I derived the event
class from wx.PyEvent and used Bind() directly on the TextCtrl
(command events propagate up the container hierarchy while regular
events don't):

import wx

class MyCustomEvent(wx.PyEvent): #or wx.PyEvent
def __init__(self, event_type, id):
wx.PyEvent.__init__(self, event_type, id)

class A(object): #Data Processing class
def __init__(self, widget_to_update):
self.widget_to_update = widget_to_update

#create the custom event:
self.my_event_type = wx.NewEventType()
self.EVT_MY_CUSTOM_EVENT =
wx.PyEventBinder(self.my_event_type, 1)

def process_data(self): #create thread here
finished = True
if finished:
self.update_gui()


def update_gui(self):
#create a custom event object and enter it in the event queue:
my_evt_obj = MyCustomEvent(self.my_event_type,
self.widget_to_update.GetId() )

self.widget_to_update.GetEventHandler().ProcessEvent(my_evt_obj)


class B(object): #Gui class
def __init__(self):
frame = wx.Frame(None, -1, "My Window")

panel = wx.Panel(frame, -1)
button = wx.Button(panel, -1, "Start Data Processing",
pos=(100, 10))
button.Bind(wx.EVT_BUTTON, self.onclick)

self.text_ctrl = wx.TextCtrl(panel, -1, "Hello World",
pos=(100, 50), size=(200, 20))

self.a = A(self.text_ctrl)
self.text_ctrl.Bind(self.a.EVT_MY_CUSTOM_EVENT,
self.on_my_custom_event)

frame.Show()

def onclick(self, event):
self.a.process_data()

def on_my_custom_event(self, event):
self.text_ctrl.SetValue("Finished Processing Data")

app = wx.PySimpleApp(redirect=False)
b = B()
app.MainLoop()
 
F

Frank Niessink

Hi Jimmy,

2008/5/12 Jimmy said:
it works! however, it seems the message can not be exchanged between
processes :(
actually what I want to do is let a running process send data to GUI
process and display it

Well, that is some crucial information you didn't mention in your
original question... I guess for the communication between processes
you can use the regular python batteries available or something like
Pyro. In your GUI process you can use a thread to listen/wait for new
information to display and then send it to the main (GUI) thread. See
http://wiki.wxpython.org/LongRunningTasks

Cheers, Frank
 

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,828
Latest member
LauraCastr

Latest Threads

Top