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

Problems with Tkinter and threads

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

--
Claus Tondering

Jul 17 '06 #1
Share this Question
Share on Google+
6 Replies


P: n/a
"Claus Tondering" <cl*************@gmail.comwrites:
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.
Jul 17 '06 #2

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

--
Claus Tondering

Jul 17 '06 #3

P: n/a
"Claus Tondering" <cl*************@gmail.comwrites:
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.
Jul 17 '06 #4

P: n/a
On Mon, 17 Jul 2006 12:58:08 +0200, Claus Tondering
<cl*************@gmail.comwrote:
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
--
python -c "print ''.join([chr(154 - ord(c)) for c in
'U(17zX(%,5.zmz5(17l8(%,5.Z*(93-965$l7+-'])"
Jul 17 '06 #5

P: n/a
Eric Brunel wrote:
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.

--
Claus Tondering

Jul 17 '06 #6

P: n/a
On Mon, 17 Jul 2006 15:20:46 +0200, Claus Tondering
<cl*************@gmail.comwrote:
Eric Brunel wrote:
>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.
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
--
python -c "print ''.join([chr(154 - ord(c)) for c in
'U(17zX(%,5.zmz5(17l8(%,5.Z*(93-965$l7+-'])"
Jul 17 '06 #7

This discussion thread is closed

Replies have been disabled for this discussion.