threading

Hello,

From all of the FAQs out there, and from personal experience, is it just not manageable to mix wxPython and threading? I would have thought that launching a thread would have been relatively benign. What is it about keeping your UI code in the main thread and putting, in my case, networking code in a thread?

I’m trying to manage a fairly low-level client interaction in the form of a traditional chat program, where text in a text box is sent to the server and the response is sent to a history multiline text box. I am learning threading and wxPython all at once, here, so I know that mixing the two is not necessarily a simple task. But I thought I was “almost there”. I successfully send the text to the server, and I finally have managed to capture the response and fire a handler. But I’ve yet to actually successfully pass the text itself, and I am finding that the second time I push the button to send text, it remains permanently in a depressed state.

Also, and this may be more about WingIDE, I am finding it difficult to put breakpoints that actually stop code. Breakpoints only appear to work in the main thread.

Is there someone out there on the other side of this threading/UI learning curve that can spare some time to help me through the final points? I want to learn how to do this correctly.

Thanks!

Vania

Hello,

From all of the FAQs out there, and from personal experience, is it just not
manageable to mix wxPython and threading?

Its manageable

I would have thought that
launching a thread would have been relatively benign. What is it about
keeping your UI code in the main thread and putting, in my case, networking
code in a thread?

It is easy launching a thread, but just putting your network code in a
thread doesn't mean anything, especially it doesn't mean that you have working
threaded WXPython app.

I'm trying to manage a fairly low-level client interaction in the form of a
traditional chat program, where text in a text box is sent to the server and
the response is sent to a history multiline text box. I am learning
threading and wxPython all at once, here, so I know that mixing the two is
not necessarily a simple task. But I thought I was "almost there". I
successfully send the text to the server, and I finally have managed to
capture the response and fire a handler. But I've yet to actually
successfully pass the text itself, and I am finding that the second time I
push the button to send text, it remains permanently in a depressed state.

Can you paste some code snipets?

Is there someone out there on the other side of this threading/UI learning
curve that can spare some time to help me through the final points? I want
to learn how to do this correctly.

Just keep doing it until it works, for a start try to imagine your
threaded app as multiple apps that perform some task. Interaction
between them has to be synchronised. I guess that when some networking event
happens you update the GUI? Basically, since your networking code is in a
thread you can't *just* do that :). Google for wx.CallAfter.

Regards
Milos

···

On Sun, Sep 10, 2006 at 12:35:48PM -0400, Vania Smrkovski wrote:

Hello,

From all of the FAQs out there, and from personal experience, is it just not
manageable to mix wxPython and threading? I would have thought that
launching a thread would have been relatively benign. What is it about
keeping your UI code in the main thread and putting, in my case, networking
code in a thread?

On some platforms, the underlying platform GUI stuff is not thread safe.
As such, you shouldn't be calling GUI stuff from anything but the thread
running app.MainLoop() . There are thread-safe mechanisms to have
non-main-thread threads interact with the GUI thread (events, polled
queues, etc.), but it sounds like you aren't doing some of them.

I'm trying to manage a fairly low-level client interaction in the form of a
traditional chat program, where text in a text box is sent to the server and
the response is sent to a history multiline text box. I am learning
threading and wxPython all at once, here, so I know that mixing the two is
not necessarily a simple task. But I thought I was "almost there". I
successfully send the text to the server, and I finally have managed to
capture the response and fire a handler. But I've yet to actually
successfully pass the text itself, and I am finding that the second time I
push the button to send text, it remains permanently in a depressed state.

Without seeing your code, I don't believe we can really help you on this
particular point.

Also, and this may be more about WingIDE, I am finding it difficult to put
breakpoints that actually stop code. Breakpoints only appear to work in the
main thread.

The debugging hooks built in to Python that WingIDE uses are (if I
remember correctly) only designed to handle single-threaded applications.
Don't use them in multi-threaded applications.

Is there someone out there on the other side of this threading/UI learning
curve that can spare some time to help me through the final points? I want
to learn how to do this correctly.

Start out here:
http://wiki.wxpython.org/index.cgi/AsynchronousSockets

That offers an asyncore-based solution to a server or client with GUI.
You can write your own poller derived from the loop() function I have
defined to be called in the MainWindow.OnPoll() function, or you can use
the threaded version and rewrite the loop() function to handle messages
from the gui (contained in the to_network queue, like ('connect', host,
port) ).

- Josiah

···

"Vania Smrkovski" <vania@pandorasdream.com> wrote:

As so often happens, after searching for a solution on my own and inching toward my goal, I suddenly give up and send an email or post a request, only to find that last inch on my next efforts.

I had everything designed okay in principle, but because I was tangling threading, call backs, networking all for the first time and all together, I had a little more in my head than I could really manage and couldn’t get it to work simply because I didn’t have everything in the right order.

I have attached the code to this email. I would appreciate some critique on how it can be cleaned up. I tried doing an MVC style, so I can separate my logic from the UI a bit better, but I finally just decided to hack into it and make a working application, so I know I need to clean it up for maintainability purposes.

Any thoughts and comments would be welcome.

ChatWindow.py (6.86 KB)

echoclient.py (1.05 KB)

echoserver.py (1.04 KB)

···

On 9/10/06, Josiah Carlson jcarlson@uci.edu wrote:

“Vania Smrkovski” vania@pandorasdream.com wrote:

Hello,

From all of the FAQs out there, and from personal experience, is it just not
manageable to mix wxPython and threading? I would have thought that
launching a thread would have been relatively benign. What is it about

keeping your UI code in the main thread and putting, in my case, networking
code in a thread?

On some platforms, the underlying platform GUI stuff is not thread safe.
As such, you shouldn’t be calling GUI stuff from anything but the thread

running app.MainLoop() . There are thread-safe mechanisms to have
non-main-thread threads interact with the GUI thread (events, polled
queues, etc.), but it sounds like you aren’t doing some of them.

I’m trying to manage a fairly low-level client interaction in the form of a
traditional chat program, where text in a text box is sent to the server and
the response is sent to a history multiline text box. I am learning

threading and wxPython all at once, here, so I know that mixing the two is
not necessarily a simple task. But I thought I was “almost there”. I
successfully send the text to the server, and I finally have managed to

capture the response and fire a handler. But I’ve yet to actually
successfully pass the text itself, and I am finding that the second time I
push the button to send text, it remains permanently in a depressed state.

Without seeing your code, I don’t believe we can really help you on this
particular point.

Also, and this may be more about WingIDE, I am finding it difficult to put
breakpoints that actually stop code. Breakpoints only appear to work in the

main thread.

The debugging hooks built in to Python that WingIDE uses are (if I
remember correctly) only designed to handle single-threaded applications.
Don’t use them in multi-threaded applications.

Is there someone out there on the other side of this threading/UI learning
curve that can spare some time to help me through the final points? I want
to learn how to do this correctly.

Start out here:
http://wiki.wxpython.org/index.cgi/AsynchronousSockets

That offers an asyncore-based solution to a server or client with GUI.

You can write your own poller derived from the loop() function I have
defined to be called in the MainWindow.OnPoll() function, or you can use
the threaded version and rewrite the loop() function to handle messages

from the gui (contained in the to_network queue, like (‘connect’, host,
port) ).

  • Josiah

Not only is it manageable, it's dead easy to do.

Just use wx.CallAfter() when to call wx stuff (widget methods,
etc) from the "non-main" thread. That's all you need to know.

···

On 2006-09-10, Vania Smrkovski <vania@pandorasdream.com> wrote:

From all of the FAQs out there, and from personal experience,
is it just not manageable to mix wxPython and threading?

--
Grant Edwards grante Yow! I think my career
                                  at is ruined!
                               visi.com

As so often happens, after searching for a solution on my own and inching
toward my goal, I suddenly give up and send an email or post a request, only
to find that last inch on my next efforts.

So...did you fix your problem?

I had everything designed okay in principle, but because I was tangling
threading, call backs, networking all for the first time and all together, I
had a little more in my head than I could really manage and couldn't get it
to work simply because I didn't have everything in the right order.

I've run echoserver.py then ChatWindow.py, and it seems to work the way
you intended it to: it connects, I can send myself chat messages, etc.,
the button doesn't stick...

There are a few quirks with the way you have implemented
echoclient.py:NetworkClient.ping() (replace the body with
self.s.sendall(message) ), and ChatWindow.py seems to be quite large
considering that it just sets up a GUI and callback registries for
incoming/outgoing messages (or maybe I'm a minimalist), but it seems all
right.

I have attached the code to this email. I would appreciate some critique on
how it can be cleaned up. I tried doing an MVC style, so I can separate my
logic from the UI a bit better, but I finally just decided to hack into it
and make a working application, so I know I need to clean it up for
maintainability purposes.

Its MVC roots can be seen. I'm personally not a big fan of MVC (I find
it horrible to write and maintain), but I would suggest sticking with
whatever works for you.

- Josiah

···

"Vania Smrkovski" <vania@pandorasdream.com> wrote:

On 9/10/06, Josiah Carlson <jcarlson@uci.edu> wrote:
>
>
> "Vania Smrkovski" <vania@pandorasdream.com> wrote:
> > Hello,
> >
> > From all of the FAQs out there, and from personal experience, is it just
> not
> > manageable to mix wxPython and threading? I would have thought that
> > launching a thread would have been relatively benign. What is it about
> > keeping your UI code in the main thread and putting, in my case,
> networking
> > code in a thread?
>
> On some platforms, the underlying platform GUI stuff is not thread safe.
> As such, you shouldn't be calling GUI stuff from anything but the thread
> running app.MainLoop() . There are thread-safe mechanisms to have
> non-main-thread threads interact with the GUI thread (events, polled
> queues, etc.), but it sounds like you aren't doing some of them.
>
>
> > I'm trying to manage a fairly low-level client interaction in the form
> of a
> > traditional chat program, where text in a text box is sent to the server
> and
> > the response is sent to a history multiline text box. I am learning
> > threading and wxPython all at once, here, so I know that mixing the two
> is
> > not necessarily a simple task. But I thought I was "almost there". I
> > successfully send the text to the server, and I finally have managed to
> > capture the response and fire a handler. But I've yet to actually
> > successfully pass the text itself, and I am finding that the second time
> I
> > push the button to send text, it remains permanently in a depressed
> state.
>
> Without seeing your code, I don't believe we can really help you on this
> particular point.
>
>
> > Also, and this may be more about WingIDE, I am finding it difficult to
> put
> > breakpoints that actually stop code. Breakpoints only appear to work in
> the
> > main thread.
>
> The debugging hooks built in to Python that WingIDE uses are (if I
> remember correctly) only designed to handle single-threaded applications.
> Don't use them in multi-threaded applications.
>
>
> > Is there someone out there on the other side of this threading/UI
> learning
> > curve that can spare some time to help me through the final points? I
> want
> > to learn how to do this correctly.
>
> Start out here:
> http://wiki.wxpython.org/index.cgi/AsynchronousSockets
>
> That offers an asyncore-based solution to a server or client with GUI.
> You can write your own poller derived from the loop() function I have
> defined to be called in the MainWindow.OnPoll() function, or you can use
> the threaded version and rewrite the loop() function to handle messages
> from the gui (contained in the to_network queue, like ('connect', host,
> port) ).
>
>
> - Josiah
>
>