Reputation: 15
I have a condition that triggers a tk_messageBox. Now, after staying for a period of let's say 10 seconds, I want it to disappear with an "ok" input without any click or interaction from the user. Is there a way that can be done?
if {condition is matched} {
set input [tk_messageBox -message $message -icon <iconType> -type <messageBoxType>]
}
Upvotes: 0
Views: 653
Reputation:
This is another possible solution using toplevel:
set message "The quick brown fox jumps over the lazy dog"
if {condition is matched} {
toplevel .new_window
wm title .new_window "Window title"
wm geometry .new_window 320x100
wm minsize .new_window 320 100
wm maxsize .new_window 320 100
wm protocol .new_window WM_DELETE_WINDOW {destroy .new_window}
wm attributes .new_window -topmost yes
set input -1
pack [label .new_window.message -text $message] -fill none -expand 1
pack [frame .new_window.buttons] -fill none -expand 1
pack [ttk::button .new_window.buttons.button1 -text "OK" -command {
set input 1
destroy .new_window
}] -side left -padx 5
pack [ttk::button .new_window.buttons.button2 -text "Cancel" -command {
set input 0
destroy .new_window
}] -side right -padx 5
after 10000 {
if {[winfo exists .new_window]} {
destroy .new_window
if {$input == -1} {
set input 1
}
}
}
}
The variable $input holds the user input value (0 or 1), after a timeout of ten seconds without a click the window will self-close with deafult value of 1 (ok).
Pay attention however, before the click or until the timeout expires the variable $input has the value of -1
EDIT: to avoid the latter uncertain behavior you'll probably want this:
set message "The quick brown fox jumps over the lazy dog"
if {condition is matched} {
toplevel .new_window
wm title .new_window "Window title"
wm geometry .new_window 320x100
wm minsize .new_window 320 100
wm maxsize .new_window 320 100
wm protocol .new_window WM_DELETE_WINDOW {
set input 1
destroy .new_window
}
wm attributes .new_window -topmost yes
if {[info exists input]} {
unset input
}
pack [label .new_window.message -text $message] -fill none -expand 1
pack [frame .new_window.buttons] -fill none -expand 1
pack [ttk::button .new_window.buttons.button1 -text "OK" -command {
set input 1
destroy .new_window
}] -side left -padx 5
pack [ttk::button .new_window.buttons.button2 -text "Cancel" -command {
set input 0
destroy .new_window
}] -side right -padx 5
after 10000 {
if {[winfo exists .new_window]} {
set input 1
destroy .new_window}
}
}
vwait input
}
To pause execution waiting for user input or the dafault answer.
Bye
Upvotes: 1
Reputation: 137727
The standard message box does not support that, as the underlying OS dialog on at least one platform (can't remember if it is Windows or macOS) doesn't support such a thing.
But you can get access to the scripted version of the dialog (which is the default one on Linux) and inject the trigger:
# Set up the timeout; I got the widget name by reading the sources
set handle [after 10000 .__tk__messagebox.no invoke]
# This is the internal name of the implementation
set answer [tk::MessageBox -type yesno -message "Foo"]
# Make sure we clear our timeout in case the user *did* pick something
after cancel $handle
Different message box types have different names for the (final part of the name of the) default button, but they'll be one of ok
, cancel
, no
or abort
, depending on dialog type. It should be obvious which. (Alternatively, just destroy the .__tk_messagebox
window. I think that also picks the default.)
Upvotes: 2