Threaded Tkinter

Michael Muller proteus at cloud9.net
Thu Jun 3 16:27:05 CEST 1999


Gerald Gutierrez wrote:
[snip]
> My first one -- I'm starting out with Tkinter. I wrote the code below,
> which will supposedly create a button with an image, that image
> changing every second. If I set the button to call swapIcons() when
> pressed, the image changes fine, but using the SpinThread, the icons
> don't change. Is this because Tkinter is not thread-safe and I cannot
> safely change the button's image property from within a thread other
> than the main one?

Tkinter is thread safe.  Tk is not.  To deal with this, the tkinter code
uses a global lock, serializing access to the Tk API.

Because of this, your background thread will block on Tkinter calls
while
the foreground thread is sitting in the mainloop.

You can deal with this by using a queue to communicate from your
background
thread and polling (arghhh!) the queue from the Tk thread like so:

  from Tkinter import Tk
  tk = Tk()

  # ...

  def poll():
     # clean out the queue
     while not myqueue.empty():
        processMessage(myqueue.get())

     # poll again in 1 second
     tk.after(1000, poll)

  poll()

Does anyone know of a better way to do this?

Alternately, in the case of your example, you could just put the image
swapping code in the poll() function.

[snip] 
> My second question -- I'd like to use Tkinter an Fnorb (CORBA)
> together as the UI and the network agent, respectively. Incoming CORBA
> calls will change appliation state and cause a change in the UI.
> 
> Now, since both Tkinter and Fnorb have their own event loops, I
> probably have to run them each in a separate thread. This is fine with
> me. The problem is that, if my first problem above is caused by the
> fact that I cannot use Tkinter in mutiple threads, I will need to send
> UI change requests for processing from within the main thread.
> 
> One way I know to do this is to have some sort of queue to which I can
> send messages. Tkinter's event loop will have to process the
> queue. How do I go about accomplishing this?
> 
> If this is not the correct way, what is?
> 

Fnorb is Tkinter aware: see examples/tkinter.  I think it deals with Tk
events and ORB requests in the same thread using select().  In my brief
experiments with this, I've had mixed results.

If the native mechanisms fail you, you can probably use the queue
approach
as identified above.

> Thanks for any help.
> 
> Please forward replies to gutier at intergate.bc.ca.


=============================================================================
michaelMuller = proteus at cloud9.net | http://www.cloud9.net/~proteus
-----------------------------------------------------------------------------
Mantra for the 60's: Tune in, turn on, drop out
Mantra for the 90's: Turn on, jack in, jerk off
=============================================================================




More information about the Python-list mailing list