Problems with Tkinter and threads

C

Claus Tondering

My Tkinter application has to receive events from a TCP connection. I
have chosen to do this in the following manner:

The TCP communication takes place in a separate thread. When I receive
data, I generate an event in the Python application thus:

app.event_generate("<<myevent1>>")

In the associated event handler, I do this:

self.label1.grid_forget()
self.label2.grid()

This works well if event is generated from a function that is called
through the after() method of the main frame. But when I send the event
from my TCP thread, the system hangs in the call to grid_forget.

Surprisingly, if I replace self.label1.grid_forget() with
self.label1.destroy(), things work well.

What can I do to call grid_forget in this event handler?
 
P

Paul Rubin

Claus Tondering said:
The TCP communication takes place in a separate thread. When I receive
data, I generate an event in the Python application thus:

app.event_generate("<<myevent1>>")

I think all bets are off when you do that. Tkinter is simply not
thread safe and generating events from another thread can trigger race
conditions and who knows. You need to self-generate events in the
gui thread with (e.g.) Tk.after, and have those events check for news
from the TCP thread. You could do that with a semaphore, or more
pythonically with a Queue.
 
C

Claus Tondering

Paul said:
Tkinter is simply not
thread safe and generating events from another thread can trigger race
conditions and who knows.

Does this mean that I cannot even call the main thread's after_idle
method from another thread?
 
P

Paul Rubin

Claus Tondering said:
Does this mean that I cannot even call the main thread's after_idle
method from another thread?

I'm not certain, I've never tried it that way since there's no way I
could be confident of its reliability even if it appeared to work.
Just use after_idle to check for a Queue item and set another
after_idle event. I generally use about 50 msec (20 hz) which doesn't
cause any noticable delay for a gui. Call the first after_idle from
the gui thread when you put up the gui.
 
E

Eric Brunel

My Tkinter application has to receive events from a TCP connection. I
have chosen to do this in the following manner:

The TCP communication takes place in a separate thread. When I receive
data, I generate an event in the Python application thus:

app.event_generate("<<myevent1>>")

This is where the problem is: if you do just a event_generate without
specifying the 'when' option, the binding is fired immediately in the
current thread. To be sure that an event is created and that the thread
switch actually happens, do:

app.event_generate("<<myevent1>>", when='tail')

and things should work fine.

HTH
 
C

Claus Tondering

Eric said:
This is where the problem is: if you do just a event_generate without
specifying the 'when' option, the binding is fired immediately in the
current thread. To be sure that an event is created and that the thread
switch actually happens, do:

app.event_generate("<<myevent1>>", when='tail')

and things should work fine.

Nice!

Obviously, there are important things that I don't know about Tkinter.
Unless I'm much mistaken, neither Fredrik Lundh's "An Introduction to
Tkinter" nor John W. Shipman's "Tkinter reference: a GUI for Python"
mentions the when='tail' option.
 
E

Eric Brunel

Nice!

Obviously, there are important things that I don't know about Tkinter.
Unless I'm much mistaken, neither Fredrik Lundh's "An Introduction to
Tkinter" nor John W. Shipman's "Tkinter reference: a GUI for Python"
mentions the when='tail' option.

The ultimate documentation is unfortunately still the tcl/tk man pages.
There is an on-line version here:

http://www.tcl.tk/man/

Once you've understood how to convert the tcl syntax to Python/Tkinter,
it's always the most up-to-date source of information.

HTH
 

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

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top