tkinter mainloop

Rick Johnson rantingrickjohnson at gmail.com
Wed Nov 19 21:04:46 EST 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:

## START CODE ##
import Tkinter as tk
root = tk.Tk()
label = tk.Label(root, text='Hello Blackness')
label.pack()
root.mainloop()
## 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
"pause"?

> > 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.


## START CODE ##
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)
    root.mainloop()
## 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