[R] tcl/tk return problem
Philippe Grosjean
phgrosjean at sciviews.org
Wed Aug 31 16:08:09 CEST 2005
Duncan Murdoch wrote:
> On 8/31/2005 8:57 AM, Prof Brian Ripley wrote:
>
>> 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!
>
>
> Yes, I agree, but I was pointing out that it is probably the wrong
> question.
>
> Duncan Murdoch
This was to provide a direct answer to the question. I think I said it
is not a good practice. For storing temporary variables for a GUI, I
prefer to use a dedicated workspace. The very simple functions
assignTemp(), getTemp() and rmTemp() in the svMisc package (SciViews
bundle) ease its use. 'TempEnv' is used in SciViews-R, and, after a
suggestion, John Fox included it also in R Commander (called 'RcmdrEnv'
there).
May be a modal Tk dialog box is all what is needed here... Although
since we are speaking about "good and bad questions", I wonder if the
whole stuff is of any value:
1°) Draw a Tk dialog just with a "Choose a directory!" and an "OK"
button is totally useless. Why not to display tkchooseDirectory()
directly? After all, the 'Cancel' button is there in case the user does
not want to proceed. This error in GUI design is to place in the same
bag as "Do you want to quit?" -> "Do you really want to quit?" -> "Are
you really sure you really want to quit?" !!!
2°) However, if the initial idea is to place other info in the Tk
dialog, it then makes sense. Now, if this is the case, it is not
necessary to put tkchooseDirectory() in the OnOK() function. The
following code is doing the job without all the problems mentioned:
> # This is because I don't have the ReadAffy() function...
> ReadAffy <- function(celfile.path) return(celfile.path)
>
> readcelfiles <- function() {
> require(tcltk)
> tt <- tktoplevel()
> tkgrid(tklabel(tt, text = "Choose a directory!"))
> tkgrid(tkbutton(tt, text = "OK",
> command = function() tkdestroy(tt)))
> tkfocus(tt)
> tkwait.window(tt)
> fileDir<-tclvalue(tkchooseDirectory())
> return(ReadAffy(celfile.path = fileDir))
> }
> readcelfiles()
So... perhaps the wrong question is not where one think it is ;-)
Best,
Philippe
> > 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.
>>
>>
>
>
>
More information about the R-help
mailing list