[R-pkg-devel] develop package with lots of tcltk in it

Dalthorp, Daniel ddalthorp at usgs.gov
Mon May 16 23:52:13 CEST 2016


That looks like a solution, Seth. I think it'll work.

Before I spend a week or so restructuring code and rewriting some of the
critical assignment statements to get the scoping right, I have a couple
questions.

(1) does the following scheme make sense or is there a more sensible way to
pull it together?
i. define tcl variables in package environment (tcl variables declared in
.R file in /R)
ii. define a new environment for error-checked, formatted variables that
can be mixed and matched in numeric calculations
[ See example below.]

(2) Is there a simple way for functions within the package to access
variables in (e.g.) .pkgenv without having to type ".pkgenv$" every time?
How can I access these when working outside the package (as a savvy user
might want to do)? [See example below.]

E.g., Package has Depends: tcltk in DESCRIPTION and .r file in /R:

.pkgenv <- new.env(parent=emptyenv())
tk.x <- tclVar()
tk.y<-tclVar()

inittest<-function(){
  tt <- tktoplevel()
  x.edit <- tkentry(tt, textvariable = tk.x, width = 5)
  x.lbl <- tklabel(tt, text = "Enter x value: ")
  y.edit<- tkentry(tt, textvariable = tk.y, width = 5)
  y.lbl <- tklabel(tt, text = "Enter y value: ")
  calc <- tkbutton(tt, text = "Calculate and save", command = function(){
    print(paste0("answer: product = ",
as.numeric(tclvalue(tk.x))*as.numeric(tclvalue(tk.y))))
    assign("x", as.numeric(tclvalue(tk.x)), envir = .pkgenv)
    assign("y", as.numeric(tclvalue(tk.y)), envir = .pkgenv)
  })
  seeStuff <- tkbutton(tt, text = "View summary", command = see)
  tkgrid(x.lbl, x.edit)
  tkgrid(y.lbl, y.edit)
  tkgrid(calc, columnspan =2)
  tkgrid(seeStuff, columnspan =2)
}
see<-function(){
  print(paste0(.pkgenv$x, " * ", .pkgenv$y, " = ", .pkgenv$x * .pkgenv$y))
}

Many thanks,

-Dan




On Thu, May 12, 2016 at 10:41 AM, Seth Wenchel <wenchel at gmail.com> wrote:

> "For users who don't know anything about R, this solution may work fine.
>> But
>> for users that do know R, it is unsatisfactory...program changes the
>> working directory, fills it with hundreds of alien-looking functions and
>> data, and crashes if working directory is changed or variables are
>> modified
>> by hand."
>
>
> Is this something that can be solved with an environment inside of the
> package?  I've done this in the past with good results.  Check out Dirk's
> rpushbullet for an example:
>
> https://github.com/eddelbuettel/rpushbullet/blob/master/R/init.R
>
> the first line of code he sets one up
> .pkgenv <- new.env(parent=emptyenv())
>
> and then creates and access objects inside of that throughout the rest of
> the package.
>
> On Thu, May 12, 2016 at 1:25 PM, Dalthorp, Daniel <ddalthorp at usgs.gov>
> wrote:
>
>> Thanks, Dirk.
>>
>> Sorry for my lack of clarity. I do want to create a package and have
>> created one and it works, but the structure is awkward. I'm hoping someone
>> can help me straighten out the organization.
>>
>> In package/R folder, I have several files that define standalone functions
>> that crunch data.
>> In package/data folder, I have several source files that construct
>> appropriate tktoplevel() windows with the desired widgets
>> To start the application, user opens a main tktoplevel() window by
>> entering
>> a simple command from R.
>> That main window has several buttons that source() files in package/data
>> folder to build a new tktoplevel(), depending on user choice
>>
>> For users who don't know anything about R, this solution may work fine.
>> But
>> for users that do know R, it is unsatisfactory...program changes the
>> working directory, fills it with hundreds of alien-looking functions and
>> data, and crashes if working directory is changed or variables are
>> modified
>> by hand.
>>
>> I came up with that goofy solution to get around two issues:
>> 1. I wasn't able to get away with defining tktoplevel windows with
>> associated widgets and storing in .Rda's packaged in /data or as
>> devtools::use_data(...internal = T), so I figured they needed to be
>> defined
>> and created as needed;
>> 2. it is easy to define the tktoplevels via code in source() files, but I
>> was having trouble with scoping and bookkeeping issues when trying to
>> define them via functions instead. It would be convenient to have all the
>> interesting data stored as globals and use the tkwidgets to edit and
>> manipulate them without having to think specifically about how to pass the
>> interesting data back and forth.
>>
>> E.g. is there an easy way to organize the following into a package that
>> does not use 'source', treats tk.x and tk.y as globals, and does not take
>> over the user's working directory with a bunch of variables like tt1,
>> x.edit, tk.x, tk.y, etc.?
>> tt1 <- tktoplevel()
>> tk.x <- tclVar()
>> x.edit <- tkentry(tt1, textvariable = tk.x, width = 5)
>> x.lbl <- tklabel(tt1, text = "Enter x value: ")
>> xcalc <- tkbutton(tt1, text = "Calculate", command = function()
>> tkmessageBox(message = tclvalue(tk.x)))
>> doMoreStuff <- tkbutton(tt1, text = "Do more...", command = function()
>>  source('doStuff_form.R'))
>> tkgrid(x.lbl, x.edit)
>> tkgrid(xcalc,doMoreStuff)
>>
>> # in doStuff_form.R:
>> tt2 <- tktoplevel()
>> tk.y<-tclVar()
>> y.edit<- tkentry(tt2, textvariable = tk.y, width = 5)
>> anscalc <- tkbutton(tt2, text = "calculate answer", command = function()
>>   tkmessageBox(message=as.numeric(tclvalue(tk.y)) *
>> as.numeric(tclvalue(tk.x)))
>> )
>> tkgrid(y.edit, anscalc)
>>
>> -Dan
>>
>> On Thu, May 12, 2016 at 8:30 AM, Dirk Eddelbuettel <edd at debian.org>
>> wrote:
>>
>> >
>> > On 11 May 2016 at 12:56, Dalthorp, Daniel wrote:
>> > | I have an R/tcltk application that is designed for use primarily by
>> > people
>> > | who don't know R and don't care to learn much about it. I'd like
>> users to
>> > | be able to use the software with a bare minimum interaction with R.
>> > |
>> > | Although the application has some 15000 lines of code in a couple
>> dozen
>> > .R
>> > | files, in essence I don't think it's much more than an elaborate
>> version
>> > of
>> > | the following:
>> > |
>> > | library(tcltk)
>> > | tt <- tktoplevel() # a required container for tk objects (textboxes,
>> > | radiobuttons, data tables, etc.)
>> > | tk.x <- tclVar() # a tcl version of user variable x
>> > | x.edit <- tkentry(tt, textvariable = tk.x, width = 5) # box for user
>> to
>> > | enter x value
>> > | x.lbl <- tklabel(tt, text = "Enter x value: ") # a fixed label
>> > | xcalc <- tkbutton(tt, text = "Calculate", command = function()
>> > | tkmessageBox(message = tclvalue(tk.x))) # button that prints x to R
>> > console
>> > | tkgrid(x.lbl, x.edit, xcalc) # a function that puts the textbox,
>> label,
>> > and
>> > | button onto the tk window
>> > |
>> > | The following doesn't work:
>> > | # tt, x.edit, x.lbl, xcalc all seem to me like an R objects that will
>> not
>> > | be modified, so I tried
>> > | devtools::use_data(tt, x.edit, x.lbl, xcalc, internal = F,
>> overwrite=T) #
>> > | (after defining them)
>> > | # tk.x is a variable that I want to assign a value to at the
>> beginning,
>> > but
>> > | user can later change the value:
>> > | devtools::use_data(tt, x.edit, x.lbl, xcalc, internal = F,
>> overwrite=T)
>> > |
>> > | The following does work, but it is not a good solution:
>> > | (1) define working directory as package/data
>> > | (2) create new tk windows via tkbutton commands = function()
>> > | source(filename)
>> > | This forces the user to use a pre-defined working directory. My
>> > application
>> > | fills that wd with several hundred functions and variables. If user
>> > changes
>> > | wd or changes values of variables that my app needs, the program
>> crashes.
>> > |
>> > | Any help would be greatly appreciated!
>> >
>> > I haven't seen the obvious stated:  Have you looked into creating a
>> > package?
>> >
>> > It can contain as much tcl/tk support code as you like,  etc pp.  And as
>> > you
>> > state you have '15000 lines of code in a couple dozen .R files' you are
>> > well
>> > passed the point where a package really is the best choice.
>> >
>> > Dirk
>> >
>> > --
>> > http://dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org
>> >
>>
>>
>>
>> --
>> Dan Dalthorp, PhD
>> USGS Forest and Rangeland Ecosystem Science Center
>> Forest Sciences Lab, Rm 189
>> 3200 SW Jefferson Way
>> Corvallis, OR 97331
>> ph: 541-750-0953
>> ddalthorp at usgs.gov
>>
>>         [[alternative HTML version deleted]]
>>
>> ______________________________________________
>> R-package-devel at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-package-devel
>>
>
>


-- 
Dan Dalthorp, PhD
USGS Forest and Rangeland Ecosystem Science Center
Forest Sciences Lab, Rm 189
3200 SW Jefferson Way
Corvallis, OR 97331
ph: 541-750-0953
ddalthorp at usgs.gov

	[[alternative HTML version deleted]]



More information about the R-package-devel mailing list