Managing toplevel windows

At start-up Tk creates a window named ‘.’. This is the most important window when working with Tk: closing it — either by the user or programmatically — means the program stops. It is also most often used to hold the main part of the application’s graphical interface.

You can create any number of new windows via the toplevel command:

   toplevel .draw
   wm title .draw Drawing

creates a new toplevel window with the title ‘Drawing’ and an associated command .draw. If you want to add a widget to this window, for instance a canvas widget (a widget suitable for displaying graphs and images and so on), include this name in the name of the new widget:

   canvas .draw.canvas
   pack .draw.canvas -fill both ;# Make it visible

As you can imagine, the widget names/commands can get pretty long. Storing the name in a variable makes it easier to set up or reorganise the GUI:

   set c [canvas .draw.canvas]
   pack $c -fill both ;# Make it visible

Toplevel windows can be resized, destroyed, brought to the front, minimized and so on programmatically with various commands. The command to do some of these things is wm, as these actions require interaction with the windowing environment, the window manager.

An important interaction with the window manager is to make sure that if the main window (.) is about to be closed, your program knows about it and can ask the user for confirmation. If you do not do that, the program will simply stop and the user may lose all his or her data. Here is the command to take care of that:

   wm protocol . WM_DELETE_WINDOW {okayToExit}

In the procedure okayToExit you can ask the user for confirmation, save all the data your program is dealing with and then destroy the window. This command works on any toplevel window, not just the main window. The WM_DELETE_WINDOW signal is sent by the window manager before the window is destroyed, allowing your application a chance to prevent it. If you just want to execute some action when a window is actually destroyed (e.g., to clean up some associated resources), then you can bind to the <Destroy> event on the window. This is called after the window is destroyed1:

  bind $window <Destroy> [list myCleanupProc $window]

The bind manual page [1] lists a number of other useful events that Tk will generate when a toplevel window changes state (e.g., visibility, size, etc.).

A common functionality is the so-called splash screen: a window without decoration that the user can not move around and that displays a logo or a short message and then disappears. This is used to show the user the application is starting up. The code fragment that follows is a trivial example:

   toplevel .splash
   wm overrideredirect .splash 1 ;# Make sure there is no title etc.

   label .splash.msg -text "Tk tutorial\nversion1.0" -font "Times 16"
   grid  .splash.msg             ;# Make it visible

   after 5000 {
       destroy .splash
   }

After 5 seconds the splash screen is removed and it is assumed that the application has been initialised.

To be really useful, we will need to centre the window. So try this:

   toplevel .splash -bg green    ;# Make it stick out (on most screens)

   wm overrideredirect .splash 1 ;# Make sure there is no title etc.

   set screenwidth  [winfo screenwidth  .]
   set screenheight [winfo screenheight .]

   set width        400
   set height       300

   wm minsize .splash $width $height  ;# Make sure it has the right size
   wm maxsize .splash $width $height

   set xsplash      [expr {($screenwidth  - $width)  / 2}]
   set ysplash      [expr {($screenheight - $height) / 2}]

   wm geometry      .splash +$xsplash+$ysplash

   label .splash.msg -text "Tk tutorial\nversion1.0" -font "Times 16" \

   .splash.msg configure -bg blue ;# We want contrast!

   grid  .splash.msg              ;# Make it visible

   after 5000 {
       destroy .splash
   }

In the process we have used the winfo command to get information about the screen the window is displayed on: its size in pixels. Also we have made sure, via wm minsize and wm maxsize that we know in advance how large the window will be: Tk windows generally adjust to the size of their contents or to the size the user requests.

If you want a window with a size the user can not change, use:

   wm resizable $window 0 0

(the two zeros indicate: not resizable in horizontal or vertical direction)

The key commands to manipulate the behaviour of the window or finding out all manner of information are wm and winfo.


1 Technically, the window still exists, but most operations on it will fail at this point.