Version 17 of Modal dialogs

Updated 2007-05-01 07:00:15 by PR

Arjen Markus I have combined the advice by Marty Backe and Erik Leunissen into a small recipe for creating modal dialog(ue)s.

I felt a receipe was needed as the proper implementation requires:

both of which are somewhat obscure commands.

GWM I have a Simple Modal Page method useful in a Wizard.

I have tested the code on UNIX (Sun Solaris with CDE window manager, Tcl/Tk 8.3.1) and Windows NT, Tcl/Tk 8.3.4). I have not paid any attention to the layout of the two windows :-)


 #
 # Create a button in the . window that displays a message box when pressed
 #
 button .hi -text Hi -command {tk_messageBox -message "Hi"}
 pack .hi
 #
 # Create a second window which acts as modal dialogue:
 # - make sure it is on top (first wait for the . window!)
 # - grab the display (locally)
 # - wait for the dialogue to disappear
 #
 # Note: the implementation is fairly rigorous. Leaving out
 #       some of the [wm] commands may work on a particular platform,
 #       but this way it works well on both UNIX and Windows)
 #       Leaving out [wm transient] gives a different appearance    pack .button
 #       on Windows.
 #
 tkwait visibility .

 toplevel .f
 button .f.b -text Close -command {destroy .f} 
 pack .f.b
 grab .f
 wm transient .f .
 wm protocol .f WM_DELETE_WINDOW {grab release .f; destroy .f}
 raise .f
 tkwait window .f 

Here's one Martin Bachem posted to the comp.lang.tcl newsgroup:

    #!/bin/sh \
    # exec wish "$0" "$@"
    proc foreground_win { w } {
       wm withdraw $w
       wm deiconify $w
    }

    proc modal_window { } {
       set w .dialog_window     
       catch { destroy $w }
       toplevel $w

       bind $ <ButtonPress> { raise $w }
       wm title $w "Dialog Window"
       # place all widgets here ...


       catch {tkwait visibility $w}
       catch {grab $w}

       foreground_win $w
    }

    button .button -text "Show Modal Dialog" -command modal_window
    grid .button
    foreground_win .

The extent to which one finds the commands grab' and wm' obscure, will probably depend a lot of ones perspective. Those familiar with programming GUI's will not find them so strange, while some people are quite proficient in this area and have no trouble to use these commands to their specific needs. As for modal dialogs, the BWidgets code for `Dialog' can serve as an example of how the details of a dialog can be controlled.

Erik Leunissen.

AM Of course, you are right :-) For me, the wm transient command was the most obscure, and I had never used grab before. I did not mean it as a comment on the commands themselves, rather that using these commands requires some care - especially in combination, they may produce different effects in different settings.

KJN The modal dialogs provided with Tk are ::tk_dialog and ::tk_messageBox. These commands use vwait rather than tkwait. The source code is rather long, and shows that modal dialogs have several subtleties.

  • ::tk_dialog - see file lib/tk*/dialog.tcl
  • ::tk_messageBox - see file lib/tk*/msgbox.tcl and wrapper proc in lib/tk*/tk.tcl

You might also want to consider looking at creating dialogs using snit - [L1 ]


Category Application - Category Dialog