Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Tkinter mainloop and threads in win32

35 views
Skip to first unread message

clw...@my-dejanews.com

unread,
Sep 22, 1998, 3:00:00 AM9/22/98
to
Hi, I am trying to write an TkInter app which has a listbox that is altered
from time to time. So what I do is start_new_thread which listens to a port
and whenever something arrives it write it to the listbox. Sounds trivial.
The code looks somewhat like this:

import thread

class MyGui(Frame):
...

def listenToPortThreadProc():
...

gui=MyGui()
thread.start_new_thread(listenToPortThreadProc, ())
gui.mainloop()

When running this code and sending data through the port I first have to click
several times on the listbox before the list is updated.
It looks as if the spawned thread has almost no priority (kind of starvation).
Even the easier example where the listenToPortThreadProc just updates the
listbox directly reacts the same.
Is this just a win32 problem?
Any hints...

Clemens
BTW: WinNT4.0 SP3, Python 1.5.1, Tcl/Tk8.0(latest)

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp Create Your Own Free Member Forum

Guido van Rossum

unread,
Sep 22, 1998, 3:00:00 AM9/22/98
to
> Hi, I am trying to write an TkInter app which has a listbox that is altered
> from time to time. So what I do is start_new_thread which listens to a port
> and whenever something arrives it write it to the listbox. Sounds trivial.
> The code looks somewhat like this:
>
> import thread
>
> class MyGui(Frame):
> ...
>
> def listenToPortThreadProc():
> ...
>
> gui=MyGui()
> thread.start_new_thread(listenToPortThreadProc, ())
> gui.mainloop()
>
> When running this code and sending data through the port I first have to click
> several times on the listbox before the list is updated.
> It looks as if the spawned thread has almost no priority (kind of starvation).
> Even the easier example where the listenToPortThreadProc just updates the
> listbox directly reacts the same.
> Is this just a win32 problem?
> Any hints...
>
> Clemens
> BTW: WinNT4.0 SP3, Python 1.5.1, Tcl/Tk8.0(latest)

Sorry, threads and Tkinter (or threads and Tcl/Tk!) are not usable
together. In 1.5.2 (in alpha for PSA members!) this will work, sort
of, but there will still be problems, especially on Windows.

I wish I could help you, but Ousterhout has made it clear that Tk will
(probably) never be thread-safe :-(

--Guido van Rossum (home page: http://www.python.org/~guido/)


Fredrik Lundh

unread,
Sep 22, 1998, 3:00:00 AM9/22/98
to
>Hi, I am trying to write an TkInter app which has a listbox that is altered
>from time to time. So what I do is start_new_thread which listens to a port
>and whenever something arrives it write it to the listbox. Sounds trivial.

Except that Tk and threads doesn't work... As of 1.5.1, Python
blocks all threads when you call the "mainloop" function, and Tk
is far from thread-safe in itself.

You can either:

a) use an idletask to poll the port

b) use a thread to poll the port and update an internal structure,
use an idletask to move data from that structure to the listbox,
and replace mainloop with something like:

while 1:
root.update()
time.sleep(0.01)

or

while 1:
_tkinter.dooneevent(_tkinter.DONT_WAIT)
time.sleep(0.01)

or something similar...

Guido seems to have eliminated the thread block in 1.5.2, but you still
shouldn't update the listbox directly from a secondary thread.

Cheers /F
fre...@pythonware.com
http://www.pythonware.com


Guido van Rossum

unread,
Sep 22, 1998, 3:00:00 AM9/22/98
to
[cc'ed back to python-list because I think the solution below is
generally handy.]

> Although this is bad news, I feel honoured to get a reply from
> Mr.Python himself...
> What (easy) alternatives do exist for building gui's from within
> Python in win32?

There's Mark Hammond's MFC bindings, which come with his win32all.exe
add-on installer (on http://starship.skyport.net/crew/mhammond/).

But that's not really *easy*...

I would suggest that instead of looking into a different GUI, you look
into a different way to accomplish your original problem -- listening
on a port while handling GUI events. A threaded solution is out, but
you can certainly use select() -- see the library docs. You may have
to do something like the following instead of the regular Tkinter main
loop:

tkroot = ...Tk root window...
while 1:
r = [...list of socket file descriptors...]
r, w, x = select.select(r, [], [], 0.02)
if r: ...handle socket input...
tkroot.update()

This will give the appearance of responsivity to both user input and
socket input, within 0.02 seconds (which is just an example -- you can
tune it to your heart's contents).

You can then use globals (or better, instance variables) to
comminucate between your socket handling code and your GUI.

Daniel Wagner

unread,
Sep 22, 1998, 3:00:00 AM9/22/98
to
On Tue, 22 Sep 1998 09:51:49 GMT, "Fredrik Lundh"
<fre...@pythonware.com> wrote:

> _tkinter.dooneevent(_tkinter.DONT_WAIT)

Where can I get more information on those (undocumented ?) internal
functions of _tkinter.pyd ?


ssch...@psipenta.com

unread,
Oct 16, 1998, 3:00:00 AM10/16/98
to
Hello,

what do you mean with "use an idletask"?

Stefan


In article <006b01bde60e$f6421b20$f29b...@pythonware.com>,

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own

Fredrik Lundh

unread,
Oct 18, 1998, 3:00:00 AM10/18/98
to
Stefan Schoene wrote:
>what do you mean with "use an idletask"?

A callback registered with "after_idle". For more information, see
"Alarm handlers and other non-event callbacks" on the following page:

http://www.pythonware.com/fredrik/tkdraft/widget.htm

0 new messages