Section 9.3. Top-Level Windows


9.3. Top-Level Windows

Tkinter GUIs always have a root window, whether you get it by default or create it explicitly by calling the Tk object constructor. This main root window is the one that opens when your program runs, and it is where you generally pack your most important widgets. In addition, Tkinter scripts can create any number of independent windows, generated and popped up on demand, by creating Toplevel widget objects.

Each Toplevel object created produces a new window on the display and automatically adds it to the program's GUI event-loop processing stream (you don't need to call the mainloop method of new windows to activate them). Example 9-3 builds a root and two pop-up windows.

Example 9-3. PP3E\Gui\Tour\toplevel0.py

 import sys from Tkinter import Toplevel, Button, Label win1 = Toplevel( )                  # two independent windows win2 = Toplevel( )                  # but part of same process Button(win1, text='Spam', command=sys.exit).pack( ) Button(win2, text='SPAM', command=sys.exit).pack( ) Label(text='Popups').pack()          # on default Tk( ) root window win1.mainloop( ) 

The toplevel0 script gets a root window by default (that's what the Label is attached to, since it doesn't specify a real parent), but it also creates two standalone Toplevel windows that appear and function independently of the root window, as seen in Figure 9-3.

Figure 9-3. Two Toplevel windows and a root window


The two Toplevel windows on the right are full-fledged windows; they can be independently iconified, maximized, and so on. Toplevels are typically used to implement multiple-window displays and pop-up modal and nonmodal dialogs (more on dialogs in the next section). They stay up until they are explicitly destroyed or until the application that created them exits.

It's important to know that although Toplevels are independently active windows, they are not separate processes; if your program exits, all of its windows are erased, including all Toplevel windows it may have created. We'll learn how to work around this rule later by launching independent GUI programs.

9.3.1. Toplevel and Tk Widgets

A Toplevel is roughly like a Frame that is split off into its own window, and has additional methods that allow you to deal with top-level window properties. The Tk widget is roughly like a Toplevel, but it is used to represent the application root window. We got one for free in Example 9-3 because the Label had a default parent; in other scripts, we've made the Tk root more explicit by creating it directly, like this:

 root = Tk( ) Label(root, text='Popups').pack()        # on explicit Tk( ) root window root.mainloop( ) 

In fact, because Tkinter GUIs are built as a hierarchy, you always get a root window by default, whether it is named explicitly, as here, or not. You should generally use the root to display top-level information of some sort; if you don't attach widgets to the root, it shows up as an odd empty window when you run your script. Technically, you can suppress the default root creation logic and make multiple root windows with the Tk widget, as in Example 9-4.

Example 9-4. PP3E\Gui\Tour\toplevel1.py

 import Tkinter from Tkinter import Tk, Button Tkinter.NoDefaultRoot( ) win1 = Tk( )         # two independent root windows win2 = Tk( ) Button(win1, text='Spam', command=win1.destroy).pack( ) Button(win2, text='SPAM', command=win2.destroy).pack( ) win1.mainloop( ) 

When run, this script displays the two pop-up windows of the screenshot in Figure 9-3 only (there is no third root window). But it's more common to use the Tk root as a main window and create Toplevel widgets for an application's pop-up windows.

9.3.2. Top-Level Window Protocols

Both Tk and Toplevel widgets export extra methods and features tailored for their top-level role, as illustrated in Example 9-5.

Example 9-5. PP3E\Gui\Tour\toplevel2.py

 ############################################################################# # pop up three new windows, with style # destroy() kills one window, quit( ) kills all windows and app;  top-level # windows have title, icon, iconify/deiconify and protocol for wm events; # there always is an app root window, whether by default or created as an # explicit Tk( ) object; all top-level windows are containers, but never # packed/gridded; Toplevel is like frame, but new window, and can have menu; ############################################################################# from Tkinter import * root = Tk( )                                                     # explicit root trees = [('The Larch!',          'light blue'),          ('The Pine!',           'light green'),          ('The Giant Redwood!',  'red')] for (tree, color) in trees:     win = Toplevel(root)                                        # new window     win.title('Sing...')                                        # set border     win.protocol('WM_DELETE_WINDOW', lambda:0)                  # ignore close     win.iconbitmap('py-blue-trans-out.ico')                     # not red Tk     msg = Button(win, text=tree, command=win.destroy)           # kills one win     msg.pack(expand=YES, fill=BOTH)     msg.config(padx=10, pady=10, bd=10, relief=RAISED)     msg.config(bg='black', fg=color, font=('times', 30, 'bold italic')) root.title('Lumberjack demo') Label(root, text='Main window', width=30).pack( ) Button(root, text='Quit All', command=root.quit).pack( )         # kills all app root.mainloop( ) 

This program adds widgets to the Tk root window, immediately pops up three Toplevel windows with attached buttons, and uses special top-level protocols. When run, it generates the scene captured in living black-and-white in Figure 9-4 (the buttons' text shows up blue, green, and red on a color display).

Figure 9-4. Three Toplevel windows with configurations


There are a few operational details worth noticing here, all of which are more obvious if you run this script on your machine:


Intercepting closes: protocol

Because the window manager close event has been intercepted by this script using the top-level widget protocol method, pressing the X in the top-right corner doesn't do anything in the three Toplevel pop ups. The name string WM_DELETE_WINDOW identifies the close operation. You can use this interface to disallow closes apart from the widgets your script creates. The function created by this script's lambda:0 does nothing but return zero.


Killing one window: destroy

Pressing the big black buttons in any one of the three pop ups only kills that pop up, because the pop up runs the widget destroy method. The other windows live on, much as you would expect of a pop-up dialog window.


Killing all windows: quit

To kill all the windows at once and end the GUI application (really, its active mainloop call), the root window's button runs the quit method instead. Pressing the root window's button ends the application.


Window titles: title

As introduced in Chapter 8, top-level window widgets (Tk and Toplevel) have a title method that lets you change the text displayed on the top border. Here, the window title text is set to the string 'Sing...' to override the default 'tk'.


Window icons: iconbitmap

The iconbitmap method changes a top-level window's icon. It accepts an icon or bitmap file and uses it for the window's icon graphic when it is both minimized and open. On Windows, pass in the name of a .ico file (this example uses one in the current directory); it will replace the normal red "Tk" icon that normally appears in the upper-lefthand corner of the window as well as in the Windows taskbar.


Geometry management

Top-level windows are containers for other widgets, much like a standalone Frame. Unlike frames, though, top-level window widgets are never themselves packed (or gridded, or placed). To embed widgets, this script passes its windows as parent arguments to label and button constructors. It is also possible to fetch the maximum window size (the physical screen display size, as a [width, height] tuple) with the maxsize( ) method, as well as set the initial size of a window with the top-level geometry(" widthhxheight+x+y") method. It is generally easier and more user-friendly to let Tkinter (or your users) work out window size for you, but display size may be used for tasks such as scaling images (see the discussion on PyPhoto in Chapter 12 for an example).

In addition, top-level window widgets support other kinds of protocols that we will utilize later on in this tour:


State

The iconify and withdraw top-level window object methods allow scripts to hide and erase a window on the fly; deiconify redraws a hidden or erased window. The state method queries or changes a window's state; valid states passed in or returned include iconic, withdrawn, zoomed (full screen on Windows; use geometry elsewhere), and normal (large enough for window content). The methods lift and lower raise and lower a window with respect to its siblings (lift is the Tk raise command). See the alarm scripts near the end of Chapter 10 for usage.


Menus

Each top-level window can have its own window menus too; both the Tk and the Toplevel widgets have a menu option used to associate a horizontal menu bar of pull-down option lists. This menu bar looks as it should on each platform on which your scripts are run. We'll explore menus early in Chapter 10.

Most top-level window-manager-related methods can also be named with a "wm_" at the front; for instance, state and protocol can also be called wm_state and wm_protocol.

Notice that the script in Example 9-3 passes its Toplevel constructor calls an explicit parent widgetthe Tk root window (that is, Toplevel(root)). Toplevels can be associated with a parent just as other widgets can, even though they are not visually embedded in their parents. I coded the script this way to avoid what seems like an odd feature; if coded instead like this:

 win = Toplevel( )                                    # new window 

and if no Tk root yet exists, this call actually generates a default Tk root window to serve as the Toplevel's parent, just like any other widget call without a parent argument. The problem is that this makes the position of the following line crucial:

 root = Tk( )                                         # explicit root 

If this line shows up above the Toplevel calls, it creates the single root window as expected. But if you move this line below the Toplevel calls, Tkinter creates a default Tk root window that is different from the one created by the script's explicit Tk call. You wind up with two Tk roots just as in Example 9-5. Move the Tk call below the Toplevel calls and rerun it to see what I mean. You'll get a fourth window that is completely empty! As a rule of thumb, to avoid such oddities, make your Tk root windows early on and make them explicit.

All of the top-level protocol interfaces are available only on top-level window widgets, but you can often access them by going through other widgets' master attributeslinks to the widget parents. For example, to set the title of a window in which a frame is contained, say something like this:

 theframe.master.title('Spam demo')    # master is the container window 

Naturally, you should do so only if you're sure that the frame will be used in only one kind of window. General-purpose attachable components coded as classes, for instance, should leave window property settings to their client applications.

Top-level widgets have additional tools, some of which we may not meet in this book. For instance, under Unix window managers, you can also set the name used on the window's icon (iconname). Because some icon options may be useful when scripts run on Unix only, see other Tk and Tkinter resources for more details on this topic. For now, the next scheduled stop on this tour explores one of the more common uses of top-level windows.




Programming Python
Programming Python
ISBN: 0596009259
EAN: 2147483647
Year: 2004
Pages: 270
Authors: Mark Lutz

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net