
The R code below illustrates some of the basic R TclTk functions required to create a non-modal dialog box. Non-modal means that the user is not forced to respond to this dialog box immediately. Instead the user can change the focus to another window and do something else before responding to this dialog box.
A Tcl variable "done" is used to keep track of the state of the dialog box (active, closed with OK, or closed with Cancel/Destroyed). The tkgrid function is used to layout the buttons on the window. The tkbind function is used to capture the event of the window being destroyed, e.g. with the cross in the upper right-hand corner or with Alt-F4 (in Windows) and to bind this event to a function which sets the state variable (done) appropriately. In order to demonstrate how to determine whether OK or Cancel was pressed, a message box is used in each case to announce the result of the Dialog Box.
# Load the TclTk package require(tcltk) # Create a new toplevel window tt <- tktoplevel() # Give the window a title tkwm.title(tt,"Simple Dialog") # Create a variable to keep track of the state of the dialog window: # If the window is active, done = 0 # If the window has been closed using the OK button, done = 1 # If the window has been closed using the Cancel button or destroyed, done = 2 done <- tclVar(0) # Create two buttons and for each one, set the value of the done variable to an appropriate value. OK.but <- tkbutton(tt,text=" OK ", command=function() tclvalue(done)<-1) Cancel.but <- tkbutton(tt,text="Cancel",command=function() tclvalue(done)<-2) # Place the two buttons on the same row in their assigned window (tt). tkgrid(OK.but,Cancel.but) # Capture the event "Destroy" (e.g. Alt-F4 in Windows) and when this happens, assign 2 to done. tkbind(tt,"<Destroy>",function() tclvalue(done)<-2) tkfocus(tt) # Do not proceed with the following code until the variable done is non-zero. # (But other processes can still run, i.e. the system is not frozen.) tkwait.variable(done) # The variable done is now non-zero, so we would like to record its value before # destroying the window tt. If we destroy it first, then done will be set to 2 # because of our earlier binding, but we want to determine whether the user pressed # OK (i.e. see whether done is equal to 1). doneVal <- as.integer(tclvalue(done)) tkdestroy(tt) if (doneVal==1) tkmessageBox(message="You pressed OK!") if (doneVal==2) tkmessageBox(message="You either pressed Cancel or destroyed the dialog!")
Running the R code above results in the following window:

The dialog is resizable by default, so you can easily make it big enough to see the title by dragging any of the edges or corners with the mouse. Notice how the grid manager automatically ensures that the OK and Cancel buttons remain centred while the window is resized.

The result of pressing OK is shown below:

The result of pressing Cancel is shown below:
