tkinter mainloop

Rick Johnson rantingrickjohnson at
Thu Nov 20 03:04:46 CET 2014

On Wednesday, November 19, 2014 5:23:38 AM UTC-6, Terry Reedy wrote:
> On 11/19/2014 3:46 AM, ast wrote:
> > mainloop() is a window method which starts the event
> > manager which tracks for events (mouse, keyboard ...) to
> > be send to the window. But if I forget the
> > root.mainloop() in my program, it works well anyway, I
> > cant see any failure. Why ?

You don't need to call "mainloop()" when building Tkinter
widgets on the command-line, but for *real* scripts i believe
you'll need to. For instance, if you run the following code
you will see a window with a label inside:

import Tkinter as tk
root = tk.Tk()
label = tk.Label(root, text='Hello Blackness')
## END CODE ##

However, if you comment out the "root.mainloop()" line you
will see nothing. Post an example that shows how you build
Tkinter GUIs without calling "mainloop".

> > Second question, is it possible to cancel a mainloop() ?

I don't think you meant to say "cancel", did you really mean

> > I neeed this feature because I have a main window "root
> > = Tk()" which opens a Toplevel secondary window "top =
> > Toplevel()" and I would like root window to be frozen
> > while the user fills the top window.

Sounds like you're trying to create a modal dialog, yes?

Tkinter has a few methods for handling such cases. One is
called "wait_window" and another is called "quit", with
"wait_window" being preferred over "quit" for most tasks.
There are also methods for setting the input "focus" and
"grab". A good example for you to look at is the
tkSimpleDialog.Dialog class. But remember, why re-invent the
wheel if you don't need to. The tkSimpleDialog.Dialog class
is a wrapper around a modal dialog behavior. And it is very
simple (imagine that!) to use.

import Tkinter as tk
from tkSimpleDialog import Dialog
from tkMessageBox import showerror
from Tkconstants import LEFT, YES, END

class MyDialog(Dialog):
    def body(self, body):
        tk.Label(body, text='Enter a value').pack(side=LEFT)
        self.entry = tk.Entry(body)
        self.entry.pack(side=LEFT, expand=YES)

    def validate(self):
        if self.entry.get() != '':
            return True
        showerror('', 'Must enter a value first, or cancel!')
        return False

    def apply(self):
        self.result = self.entry.get()

if __name__ == '__main__':
    root = tk.Tk()
    root.update_idletasks() # Don't do this normally
    d = MyDialog(root)
    print 'User Entered: {0!r}'.format(d.result)
## END CODE ##

However, i must admit the API is both poorly written, uses
poor naming conventions for the hooks, and also trys to be
too implicit by auto-showing the dialog. I rewrote the entire 
class many years ago and have not missed it one bit. 

> There are methods for freezing a widget.  Something like
> root.withdraw. But there is more than one for doing
> slightly different things - Terry Jan Reedy

Actually that's not true Terry. The "Toplevel" method named
"withdraw" will cause a window to be hidden from view. And
if the OP tries to use withdraw on the root window, the root
and *ALL* child window(s) will be withdrawn, leaving no visible
windows at all -- at least in the example he gave anyhow.

More information about the Python-list mailing list