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

Dalthorp, Daniel ddalthorp at usgs.gov
Thu May 12 19:25:25 CEST 2016


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]]



More information about the R-package-devel mailing list