[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