[R] How to interrupt a loop by pressing a key?
Barry Rowlingson
b.rowlingson at lancaster.ac.uk
Tue Jan 15 19:50:14 CET 2008
Bruno Jesus wrote:
> So... back to the initial question. Can I break the cycle with a signal
> from the keyboard?
The following code, slightly modified from:
http://www.sciviews.org/_rgui/tcltk/OKCancelDialog.html
lets you interrupt an analysis by clicking on a dialog box, using the
tcltk package. Yes, I know it's not a keypress, but maybe this will do.
You can probably map a keypress to the TclTk dialog anyway, or do
something really tricky with Tk events...
Copy the following into a file, test.R, make sure lines aren't badly
broken, and source("test.R").
If you are using Emacs and ESS then you may have to thump Ctrl-G to
wake up emacs to what is happening...
require(tcltk) # Load the TclTk package
tt <- tktoplevel() # Create a new toplevel window
tktitle(tt) <- "Simple Dialog" # Give the window a title
# 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) # tclVar() creates a Tcl variable
# 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) # Place the focus to our tk window
for(i in 1:1000){
# now do our 1000 iterations of whatever, checking the 'done' variable
# to see
# if the user clicked the dialog while we were busy.
cat("Iteration ",i,"\n")
Sys.sleep(1)
doneVal <- as.integer(tclvalue(done)) # Get Tcl variable
if(doneVal != 0)break
}
tkdestroy(tt)
# Test the result
if (doneVal == 0) tkmessageBox(message = "Analysis finished okay")
if (doneVal == 1) tkmessageBox(message = "You interrupted the analysis")
if (doneVal == 2) tkmessageBox(message = "You either pressed Cancel or
destroyed the dialog!")
More information about the R-help
mailing list