[Rd] Building an R GUI using gWidgets and RGtk2
Gabor Grothendieck
ggrothendieck at gmail.com
Sat Sep 15 05:06:35 CEST 2007
On 9/14/07, Gabor Grothendieck <ggrothendieck at gmail.com> wrote:
> On 9/14/07, Gerlanc, Daniel <Daniel.Gerlanc at geodecapital.com> wrote:
> > Hello,
> >
> > I'm developing a GUI in R that will be used to monitor financial
> > portfolio performance. The GUI will be distributed as an R package. So
> > far, I've decided to use the "cairoDevice", "RGtk2", "gWidgets", and
> > "gWidgetsRGtk2" packages to develop the GUI. I am trying to decide what
> > would be the best way to structure the GUI would be.
> >
> > I've considered 3 approaches to building the GUI. The first would be to
> > use S4 classes. I would create parent "gui" object that would store
> > widgets or containers in slots. Other more specialized guis for
> > different purposes would extend this parent "gui" object. The
> > difficulty in this approach is R's use of pass-by-value. Once the gui
> > object has been created, changing any of the slots of the gui requires
> > returning a new GUI object or saving one off in a higher level
> > environment and editing the slots directly. Editing the slots directly
> > would completely bypass the S4 method dispatch.
> >
> > Another approach would be more functional. I would create variables
> > that are global within the package or in their own environment and
> > define the package function closures within this environment. This
> > could work, but the code could get noisy when calls to have be made to
> > distinguish between local variable assignment within the environment of
> > the functions and assignment within the namespace of the package.
> >
> > The third approach I've been considering is using the R.oo package. I
> > have never used this package before but it appears to provide similar OO
> > features to Java. Because it allows references, it would seem to
> > provide the features I'm looking for from both the S4 and functional
> > approaches.
> >
> > Any comments or suggestions on these different approaches would be
> > appreciated.
> >
> > Thank you.
> >
> > Sincerely,
> >
> > Daniel Gerlanc
> A fourth approach would be the proto package. It provides a thin
> layer over environments making use of the prototype (aka object-based)
> style of programming which is fundamental different relative to
> class-based programming (although it is powerful enough to encompass
> class based programming). The gsubfn package uses proto objects
> as generalizations of replacement strings that hold state from one replacement
> to the next. An application that may be closer to yours that uses proto
> is ggplot2 which is a recent grid-based plotting package. The home page is at
> http://r-proto.googlecode.com .
> See the paper on prototype programming linked on the home page as well
> as the package vignette.
Just to illustrate this further here is a simple example of gWidgets and
proto. In this example we create a proto object, p, that corresponds to
an ok/cancel dialogue labelled Hello and that prints Hello when OK is
pressed. The components of p are go, msg and handler. msg is
a character string, go is a method and handler is a function (to be
a method it would have to pass the proto object as its first arg).
q is created as a child of p so q gets components via
delegation from p. q overrides msg which was "Hello" in p but is "Bye"
in q. q acts the same as p except the label is Bye and q prints Bye when
OK is pressed. Note that we pass the proto object to the handler via
the action= argument. Here we used a dot (.) to denote the current
object but you could use this or self or any variable name you prefer.
library(proto)
library(gWidgets)
p <- proto(go = function(.) {
w = gwindow()
g = ggroup(container = w)
g.i = ggroup(horizontal=FALSE, container = g)
glabel(.$msg, container = g.i, expand = TRUE)
g.i.b = ggroup(container = g.i)
addSpring(g.i.b)
gbutton("ok", handler = with(., handler), action = ., container = g.i.b)
gbutton("cancel", handler = function(h, ...) dispose(w),
container = g.i.b)
},
msg = "Hello",
handler = function(h, ...) {
cat("\n", h$action$msg, "\n")
dispose(h$obj)
}
)
p$go() # press ok and Hello is printed
q <- p$proto(msg = "Bye") # q is child of p overriding msg
q$go() # press ok and Bye is printed
More information about the R-devel
mailing list