[Tkinter-discuss] Returning control from a toplevel

Wayne Werner waynejwerner at gmail.com
Wed Apr 28 22:06:18 CEST 2010


On Wed, Apr 28, 2010 at 1:32 PM, Michael Lange <klappnase at web.de> wrote:

> That's a lot of questions :)
> Maybe one of the gurus here can explain better than me why exactly
> there must not be more than one mainloop. I think the problem with your
> stopped while loop happens because the mainloop() does not return until
> the main application window is destroyed. You can verify this by adding
> a "print" statement after the second mainloop() to the new() function
> in your previous example.
> If you are not able to display images in the Toplevel window there is
> surely something else wrong with your code, so maybe you can post a
> short code example that shows this problem? It should definitely be
> possible to put images in a Toplevel without a second mainloop :)
>

 The reason that two mainloops don't get along is because of what they're
doing.

Imagine:

while True:
   do A
while True:
   do B

You'll have a lot of A, but no more B. That's an overly simplified version
of what's going on, but it's still accurate enough. Tkinter has an event
loop that has a few tasks: 1) draw everything, 2) listen for events such as
keypresses and mouse clicks, 3) emit events/call callbacks

There may be some others, but those are the essential ones. When you try to
create two mainloops all of those draw/listen/emit tasks collide and it's
not pretty. Michael is correct that you should be able to draw the image
without having to resort to two mainloops. Without seeing your code what I
would guess is the problem is that you're spawning the window from within
your infinite loop - and guess what? Remember those events that the mainloop
is supposed to be taking care of? They never happen because the mainloop is
awaiting control.

A quick example:

import Tkinter as tk

def looper():
    while True:
         pass

root = tk.Tk()
b = tk.Button(root, text="Hi", command=looper)
b.pack()
root.mainloop()

Fire that up (from command line preferably) and click the button. Notice how
you cannot do anything else? That's because the mainloop is waiting for
control that it never gets because it's continually executing the while
loop. You now have to kill or ctrl+c the program to break out of the
infinite loop. But notice that if you haven't pushed anything else and just
hit ctrl+c then your program is still running. The control has been passed
back to the main loop of your program. Another interesting thing to notice
is (at least it works for me) if you click the close button while the
infinite loop is waiting, and then ctrl+c the program quits. Why? Because
the click was passed into tkinter's event queue and it was just waiting to
be handled.

Anyhow, HTH,
Wayne
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tkinter-discuss/attachments/20100428/7effb21b/attachment.html>


More information about the Tkinter-discuss mailing list