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 <wenc...@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 <ddalth...@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 <e...@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 | e...@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 >> ddalth...@usgs.gov >> >> [[alternative HTML version deleted]] >> >> ______________________________________________ >> R-package-devel@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 ddalth...@usgs.gov [[alternative HTML version deleted]] ______________________________________________ R-package-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-package-devel