A modal dialog box requires the user to respond to it before changing the focus to other windows within
the application. The Tk command tk_dialog is designed for this purpose, and can be called in R TclTk,
using the tkdialog function. However, the method illustrated below will use the tktoplevel
function and call tkgrab.set and tkgrab.release explicitly, rather than relying on
tkdialog to call them automatically.
The following example defines a subroutine which creates a simple modal dialog box using tktoplevel to
create the dialog window, and using tkgrab.set and tkgrab.release to force the user to respond
to this dialog before changing focus to other window(s) in the applciation.
modalDialog <- function(title,question,entryInit,entryWidth=20,returnValOnCancel="ID_CANCEL")
{
dlg <- tktoplevel()
tkwm.deiconify(dlg)
tkgrab.set(dlg)
tkfocus(dlg)
tkwm.title(dlg,title)
textEntryVarTcl <- tclVar(paste(entryInit))
textEntryWidget <- tkentry(dlg,width=paste(entryWidth),textvariable=textEntryVarTcl)
tkgrid(tklabel(dlg,text=" "))
tkgrid(tklabel(dlg,text=question),textEntryWidget)
tkgrid(tklabel(dlg,text=" "))
ReturnVal <- returnValOnCancel
onOK <- function()
{
ReturnVal <<- tclvalue(textEntryVarTcl)
tkgrab.release(dlg)
tkdestroy(dlg)
tkfocus(ttMain)
}
onCancel <- function()
{
ReturnVal <<- returnValOnCancel
tkgrab.release(dlg)
tkdestroy(dlg)
tkfocus(ttMain)
}
OK.but <-tkbutton(dlg,text=" OK ",command=onOK)
Cancel.but <-tkbutton(dlg,text=" Cancel ",command=onCancel)
tkgrid(OK.but,Cancel.but)
tkgrid(tklabel(dlg,text=" "))
tkfocus(dlg)
tkbind(dlg, "<Destroy>", function() {tkgrab.release(dlg);tkfocus(ttMain)})
tkbind(textEntryWidget, "<Return>", onOK)
tkwait.window(dlg)
return(ReturnVal)
}
# Create a "main" window with a button which activates our dialog.
require(tcltk)
ttMain <- tktoplevel()
tkwm.title(ttMain,"ttMain")
launchDialog <- function()
{
ReturnVal <- modalDialog("First Name Entry","Enter Your First Name","")
if (ReturnVal=="ID_CANCEL")
return()
tkmessageBox(title="Greeting",message=paste("Hello, ",ReturnVal,".",sep=""))
}
launchDlg.button <- tkbutton(ttMain,text="Launch Dialog",command=launchDialog)
tkpack(launchDlg.button)
Clicking on the "Launch Dialog" gives a modal dialog box, i.e. you must respond to it before you can change the focus back to the main window in the Tk application.
Clicking "OK" gives the following message box: