Skip to content

tcl/tk return problem

7 messages · deggle, Brian Ripley, Duncan Murdoch +1 more

#
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.

Could anyone give me a hint?

Thank you very much,
Daniela
#
deggle wrote:
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.
Best

Philippe Grosjean
#
On Wed, 31 Aug 2005, Philippe Grosjean wrote:

            
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.)
#
Prof Brian Ripley wrote:
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.  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.

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.

Duncan Murdoch
#
On Wed, 31 Aug 2005, Duncan Murdoch wrote:

            
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.
One could argue the user who pressed the button does: it is the user
workspace.

  
    
#
On 8/31/2005 8:57 AM, Prof Brian Ripley wrote:
Yes, I agree, but I was pointing out that it is probably the wrong question.

Duncan Murdoch

 > If you use a non-modal tcltk dialog you
#
Duncan Murdoch wrote:
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