tcl/tk return problem
On Wed, 31 Aug 2005, Duncan Murdoch wrote:
Prof Brian Ripley wrote:
On Wed, 31 Aug 2005, Philippe Grosjean wrote:
deggle wrote:
Hello,
I'm very new in working with tcl/tk in R and have a problem which will
probably
sound silly to most of you.
Here is the code I have problems with:
readcelfiles <- function()
{
require(tcltk)
tt <- tktoplevel()
tkgrid(tklabel(tt,text="Choose a directory!"))
OnOK <- function()
{
fileDir<-tclvalue(tkchooseDirectory())
data.raw <- ReadAffy(celfile.path=fileDir)
#return(data.raw)
}
OK.but <- tkbutton(tt,text="OK",command=OnOK)
tkgrid(OK.but)
tkfocus(tt)
}
So after clicking on my "OK" button, I choose my directory and read the
cel-files.
But now I want to return the object to my workspace ... "return" doesn't
work here.
I suppose you mean in the User Workspace. Your OnOK function should look
like that:
OnOK <- function() {
fileDir<-tclvalue(tkchooseDirectory())
data.raw <<- ReadAffy(celfile.path=fileDir)
}
Note that the function overwrites any existing 'data.raw', so this could
be dangerous. Writting directly in the User Workspace is not advised
from inside a function, but here, it is the simplest way to return a
result from a tk widget action.
Maybe simplest, but not a very good way. See
R_SOURCES/src/library/tcltk/R/utils.R for ideas on how to write a modal
dialog box that returns the value selected.
One problem with <<- is that it does not necessarily write in the
workspace. You need
assign("data.raw", ReadAffy(celfile.path=fileDir), envir=.GlobalEnv)
to be sure of that. (The example code I quote does use <<- but in a
controlled way.)
This works, and you weren't suggesting it as a good style, but I'd like to say it's really a bad style to write to .GlobalEnv.
It was the question asked! If you use a non-modal tcltk dialog you have little choice, as the parent function will have returned and vanished long ago. Now, having a widget firing off R commands independently of the command line is not a great idea (R's evaluator is not multithreaded and this could be interspersed in another computation) so there is a lot to be said for using dialog boxes modally.
The controlled use of <<- as in tk_select.list from the file you quoted is really the best way to solve this problem. As a general rule, you shouldn't stomp on something you don't own, and functions don't own variables in .GlobalEnv.
One could argue the user who pressed the button does: it is the user workspace.
What tk_select.list does is define OnOK locally, and use <<- to write to the tk_select.list environment. Then the result can be manipulated and returned politely, without stomping on anything anywhere.
Brian D. Ripley, ripley at stats.ox.ac.uk Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ University of Oxford, Tel: +44 1865 272861 (self) 1 South Parks Road, +44 1865 272860 (secr) Oxford OX1 3TG, UK Fax: +44 1865 272595