Updated 2016-11-17 20:24:19 by oehhar

The tk_messageBox widget opens a modal dialog and waits for user response.

See man page here: http://www.tcl.tk/man/tcl/TkCmd/messageBox.htm

See also: messageBox, ttk::messageBox.

This command is recommended over use of tk_dialog.


tk_messageBox ?option value ...?


This procedure creates and displays a message window with an application-specified message, an icon and a set of buttons. Each of the buttons in the message window is identified by a unique symbolic name (see the -type options). After the message window is popped up, tk_messageBox waits for the user to select one of the buttons. Then it returns the symbolic name of the selected button. The following option-value pairs are supported:

-default name

Name gives the symbolic name of the default button for this message window ('ok', 'cancel', and so on). See -type for a list of the symbolic names. If this option is not specified, the first button in the dialog will be made the default.

-icon iconImage

Specifies an icon to display. IconImage must be one of the following: error, info, question or warning. If this option is not specified, then the info icon will be displayed.

-message string

Specifies the message to display in this message box.

-detail string

New in 8.5. Specifies additional detail to the main message. Displayed in a smaller font where possible.

-parent window

Makes window the logical parent of the message box. The message box is displayed on top of its parent window.

-title titleString

Specifies a string to display as the title of the message box. The default value is an empty string.

-type predefinedType

Arranges for a predefined set of buttons to be displayed. The following values are possible for predefinedType:
Displays three buttons whose symbolic names are abort, retry and ignore.
Displays one button whose symbolic name is ok.
Displays two buttons whose symbolic names are ok and cancel.
Displays two buttons whose symbolic names are retry and cancel.
Displays two buttons whose symbolic names are yes and no.
Displays three buttons whose symbolic names are yes, no and cancel.

 set answer [tk_messageBox -message "Really quit?" -type yesno -icon question]
 switch -- $answer {
   yes exit
   no {tk_messageBox -message "I know you like this application!" -type ok}

With recent versions, the Windows messageBox is "native", while the Unix one continues to rely on the implementation visible in ./library/msgbox.tcl. Before version 8.something, both Win* and Unix used msgbox.tcl [what about MacOS?]. Notice that this means that, if there's something about messageBox you don't like, you have the source code readily available for your enhancements.

[Detail example of how to do this needed right here.]

DKF: No. There has never been a non-native version of tk_messageBox on Windows and Macintosh, though tk_dialog is an approximation (and implemented purely in Tcl scripts) on all platforms.

Donald Arseneau mentions on comp.lang.tcl that this widget is not written to be re-entrant. The result of this means that if there are two instances of tk_messageBox opened at the same time, a button clicked in one of them is seen by all of them! This is a bug in the widget that has been submitted to the sf.net bug database, but doesn't appear to be resolved as of Fall 2003.

[Insert example of how to use option database with messageBox.]

On Unix, the default font for message boxes is Times 18, which is way too fat for longer text. Before creating a messageBox, just add the line
 option add *Dialog.msg.font {Times 12}

to get a better readable font (won't hurt in Windows, where native message boxes are used anyway). (RS)

The wraplength also defaults to 3 inches but can be overriden the same way for long messages (BBH)
 option add *Dialog.msg.wrapLength 6i

Martin Lemburg Because of the need to have a messagebox in the tclsh, I wrote a tclsh version ... tcl_messageBox. To download the stubs enabled version (tcl v8.1 and higher) use
    (package only)
    (includes the source, project files, etc.)

The syntax is simular to the tk_messageBox:
   tcl_messageBox ?option optionArg option optionArg ...?


  • -align: left or right
  • -default: depends on the given type
  • -icon: exclamation, warning, info(rmation), asterisk, question, stop, error or hand
  • -message: string, may be empty
  • -modal: app(lication), window, system or task
  • -title: string, may be empty
  • -type: abortretryignore, ok, okcancel, retrycancel, yesno or yesnocancel
  • -help: this text

Keep stacking order (OS: Windows NT)

HaO: On windows, the tk_messageBox command sets the toplevel . to the top of the window stacking order. After the message box, the toplevel . gets the focus.

To "repair" this behavior on tcl8.4 one can protect the windows over . by
wm attributes -topmost 1

and save the focus over the routine.
# tk_messageBox for Windows which keeps focus and stacking order
proc messageBox args {
    # > Save focus
    set Focus [focus]
    # > Get the toplevels above . and set topmost attribute
    set lWindows [wm stackorder .]
    set TopPos [lsearch $lWindows .]
    if {-1 != $TopPos && $TopPos != [llength $lWindows]} {
        incr TopPos
        set lWindows [lrange $lWindows $TopPos end]
        foreach Wi $lWindows {
            wm attributes $Wi -topmost 1
    } else {
        unset lWindows
    # > invoke message box
    set Res [eval tk_messageBox $args]
    set Res [eval tk_messageBox $args]
    # > unset topmost attribute
    if {[info exists lWindows]} {
        foreach Wi $lWindows {
            wm attributes $Wi -topmost 0
    # > Restore focus
    # Set focus to last widget if we had the focus before
    # otherwise set it to the topmost window
    if {[info exists lWindows]} {
        focus -force [lindex $lWindows end]
    } elseif {0 < [string length $Focus]} {
        focus -force $Focus
    return $Res

# Test program for demonstration:
foreach Wi {. .t1 .t2} {
    catch {toplevel $Wi}
    pack [button $Wi.b1 -text messageBox -command "messageBox -message So..."]
    pack [button $Wi.b2 -text tk_messageBox -command "tk_messageBox -message well..."]

MG thinks a more correct solution is to use the -parent option to set which widget the message box belongs to. It only defaults to '.' if you don't tell it otherwise.

[Willem] Re: Harald's script, the 'if' statement under "Set focus to...": I think it is better to always first use lWindows if available, ie., turn around the two checks. I found this improved behaviour when there are more than 2 windows (otherwise an active window can end up beneath an inactive one).

HaO: Ok, corrected, thanks.

Give focus back to foreign windows on Application without any visible window (OS: Windows NT)

HaO 2016-11-17: I have an application without any shown window, only a Taskbar Icon (winicon extension). Thus, always another Application has the input focus.

When showing a tk_messageBox, it gets into front and the foreign application looses focus. When the message box is closed, the foreign application does not get the focus back. To acheve this, I use the code:
# > Save handle of foreground window
if {$::tcl_platform(os) eq "Windows NT"} {
        package require twapi_ui
        catch { set foregroundWindow [twapi::get_foreground_window] }
# > Call message box
set Res [tk_messageBox ...]
# > Restore foreground window
if {[info exists foregroundWindow]} {
        catch { twapi::set_foreground_window $ForegroundWindow }

[Incorporate material from this comp.lang.tcl thread [1].]

RS has grown into the habit of coding
 set about "Short descriptive text for the app, at beginning of source file
 (also serves for some documentation)"
 button .a -text About -command [list tk_messageBox -message $about]

Timed-out message box: The native tk_messageBox on Windows can not be closed by script (say after a time-out of e.g. 3 seconds). If you want this (and don't mind oldish bitmap icons), try a tk_dialog this instead:
 after 3000 {destroy .dialog1}
 tk_dialog .dialog1 "Dear user:" "Click ok!" info 0 OK

The same technique can be used to reconfigure the dialog's message widget:
 after 1 {.d.msg config -font {Arial 12 italic}}
 tk_dialog .d Title "This is the main message" info 0 OK ;# RS

[MF] Pure Tcl message box. I am looking for a way to display a message box (Windows only) w/o using Tk or any other extensions. Thinking about calling wsh (Windows Shell) with echo or popup commands, but cannot find a way. Any ideas?

NEM Well, you can exec wsh. You'll have to check the wsh documentation to see what arguments it expects. It would seem easier to just package require Tk and then pop-up a dialog box, though (with the advantage that it also works on non-Microsoft platforms).

Beware The code here works fine for me on windows, saved as 'test.vbs'. Then you'd just have to exec it properly.

[gorjuela] - 2009-11-06 14:56:10

Is there a problem with tk_messageBox on Mac OS X (10.5) ? In Wish8.5, try the following:
     tk_messageBox -type ok -icon error

a dialog with the standard Wish8.5 frog icon appears. Press ok to dismiss the dialog.
     tk_messageBox -type ok -icon info

exactly the same dialog, with the same frog icon, appears. Press ok to dismiss the dialog.
     tk_messageBox -type ok -icon question

now the dialog has a different icon-- the exclamation point within a yellow triangle (with a little frog icon superimposed), which is better associated with a warning. Press ok to dismiss the dialog, and finally...
     tk_messageBox -type ok -icon warning

exactly the same dialog as the previous <question> dialog, with the same exclamation point.

In contrase, if one does this in Wish8.5 on Windows, one gets four distinct icons: red circle w/white X, an 'i', a '?', and a '!', respectively.

Or is there something else that has to be specified for OS X?

[magicknees] - 2012-07-11 20:38:29

<I am using the tk_messagebox as a Help->About dialog box. I wanted to only display one box no matter how many times they clicked on About. I also wanted user to be able to continue working while the box was displayed. Since I couldn't capture the name I put a little semaphore flag in:
set GTT_SIM::aboutflag ""

proc GTT_SIM:help_about { } {
    if { $GTT_SIM::aboutflag == "busy" } { return }
    set GTT_SIM::aboutflag "busy"
    tk_messageBox -parent . -title "About GTT Simulation" -message {
Automating Simulations on ABC Harness systems

Making It Easier For You To Do Your Job

Created by John, GTT Systems Engineering, 18951
    } -type ok

    set GTT_SIM::aboutflag ""


EE says: How can the user continue working while this is displayed? For me, the message box appears to be a modal dialog.

Note that you can make you own idempotent window fairly easily. Just use winfo exists. Your help_about function can do the following:
if {[winfo exists .help_about]} {
    wm deiconify .help_about;
    raise .help_about;
    focus .help_about;

right at the beginning, and if the About window already exists, it'll just raise and focus it instead of making a new one. This will work whether the "Ok" button destroys the window or merely wm withdraw's it. (Also note that if the "Ok" button uses wm withdraw instead of destroy to dismiss the window, you also have the option of using wm protocol to prevent the window from being destroyed by the window manager when the X is clicked.
wm protocol .help_about WM_DELETE_WINDOW {wm withdraw .help_about}

[joseamirandavelez] - 2013-02-26 15:18:53

How do I get a multi line message? I'm trying to use:

tk_messageBox -message [concat "Mass:" $daMass "\nVolume:" $daVolume "\nArea:" $daArea "\nCGX=" $x "\nCGY=" $y "\nCGZ=" $z]

but the new line escape does not work. It just ignores it...

'''APE - 2013-02-26 16:44:00 try the following :

tk_messageBox -message "Mass: $daMass \nVolume: $daVolume \nArea: $daArea \nCGX= $x \nCGY= $y \nCGZ= $z"