You could use wx.WakeUpIdle() to kick the idle loop every time you have an action to do. I use this method to show status messages from threads.
Regards, Phil
···
At 05:47 AM 7/4/2008, you wrote:
Hi all,
I wanted to have some thoughts on this. I am using wxPython at work
now (great by the way!) but I am constantly writing inter-thread
communication code. The latest thing I need to do is set up a number
of scalable servers (that listen to a certain socket) that receive an
XML file and the GUI (wxPython) will have to process that.
The way it can be done is making a wx.Timer, and check something like
a thread safe queue for messages. But the GUI already runs in a
thread. That is constantly doing 'nothing' between events. It would be
nice if I get something like a wx.MailBoxEvent if there is an item in
a thread safe mailbox. Something like;
---
# create a queue and a thread that uses the queue
self.queue = queue.Queue()
self._thread = thread.Thread(self.queue)
So when the main thread runs internally and senses that there are
items in the queue, it could call between events the _onItemPresent
handler. It would greatly improve the simplicity and also
responsiveness because checking on wx.Timer base always introduces a
lag.
Is something like this difficult to add to wxPython or can this be
done in a seperate more elegant way then the wx.Timer solution I
sketched? The advantage of this is that multiple queue's can be added
dynamically without much code overhead, and the main thread that runs
free most of the time will take care of notifications.
My suggestions:
1. Rather than write your own socket server, use an XML-RPC server.
More specifically something like:
That would not be possible. the XML I receive is in an ORACLE/DbII
format. What I need(ed) to write was a label printer emulator. It
exposes a port on TCP/IP that a genuine piece of software could
connect to and display the label data inside. I wanted to make a
number of threads all bound to a certain port to be able to emulate
multiple printers with this piece of software.
Hi Phil.
You could use wx.WakeUpIdle() to kick the idle loop every time you have an action to do. I use this
method to show status messages from threads.
Well I thought about that but that means once again I would have to
write the management code myself, and perform extra tricks to get to
the message data. It would be a nice idea that wxWidgets / wxPython
has an internal wxMailBox that can be accessed by threads and in your
main loop an event is generated when a message is posted. This will
take away the extra administration
I would like to write something like that myself, but it requires
modifying the main loop of wxWidgets as it also needs to check for
additional stuff (like the availability of a message) in the mailbox
and generate an event when one occurs. As you can create multiple
mailboxes it could be a nice way to communicate with threads, intead
of the threading sample where the thread creates a wx.CommandEvent and
an obscure menu ID which gets fired when something has to be passed
back.
Here is one way to implement something like that.
* Derive a class from Queue.Queue in the python library.
* Override put() to also call wx.WakeUpIdle()
* The derived class can bind a handler to wx.GetApp() for the EVT_IDLE event. When the handler is called check if the queue has items in it, if so pull one item and do whatever you want with it. If there are more items in the queue then call event.RequestMore so you'll get another idle event soon. Be sure to call event.Skip so the app's default idle handler will still be called.
···
--
Robin Dunn
Software Craftsman http://wxPython.org Java give you jitters? Relax with wxPython!