Playing with GUIs in R with RGtk2

[This article was first published on Rexamine » Blog/R-bloggers, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Sometimes when we create some nice functions which we want to show other people who don’t know R we can do two things. We can teach them R what is not easy task which also takes time or we can make GUI allowing them to use these functions without any knowledge of R. This post is my first attempt to create a GUI in R. Although it can be done in many ways, we will use the package RGtk2, so before we start you will need:

require("RGtk2")

I will try to show you making GUI on an example. I want to make an application which works like calculator. It should have two text fields: first with a expression to calculate and second with result. I want to include button which makes it calculate. It should display error message when there is a mistake in the expression. Also I want two buttons to insert sin() and cos () into text field. Last thing is a combobox allowing us to choose between integer and double result.

Firstly we need to make window and frame.

window <- gtkWindow()
window["title"] <- "Calculator"


frame <- gtkFrameNew("Calculate")
window$add(frame)

It should look like this:

Now, let’s make two boxes. To the first box we put components vertically and horizontally to the second box.

box1 <- gtkVBoxNew()
box1$setBorderWidth(30)
frame$add(box1)   #add box1 to the frame

box2 <- gtkHBoxNew(spacing= 10) #distance between elements
box2$setBorderWidth(24)

This should look exactly as before because we don’t have any component in boxes yet, also box2 isn’t even added to our window. So let’s put some elements in.

TextToCalculate<- gtkEntryNew() #text field with expresion to calculate
TextToCalculate$setWidthChars(25)
box1$packStart(TextToCalculate)

label = gtkLabelNewWithMnemonic("Result") #text label
box1$packStart(label)

result<- gtkEntryNew() #text field with result of our calculation
result$setWidthChars(25)
box1$packStart(result)

box2 <- gtkHBoxNew(spacing= 10) # distance between elements
box2$setBorderWidth(24)
box1$packStart(box2)

Calculate <- gtkButton("Calculate")
box2$packStart(Calculate,fill=F) #button which will start calculating

Sin <- gtkButton("Sin") #button to paste sin() to TextToCalculate
box2$packStart(Sin,fill=F)

Cos <- gtkButton("Cos") #button to paste cos() to TextToCalculate
box2$packStart(Cos,fill=F)

model<-rGtkDataFrame(c("double","integer"))
combobox <- gtkComboBox(model)
#combobox allowing to decide whether we want result as integer or double

crt <- gtkCellRendererText()
combobox$packStart(crt)
combobox$addAttribute(crt, "text", 0)

gtkComboBoxSetActive(combobox,0)
box2$packStart(combobox)

Now we should have something like this:

Note that our window gets bigger when we put bigger components in it. However nothing is working as intended. We need to explain buttons what to do when we click them:

DoCalculation<-function(button)
{

  if ((TextToCalculate$getText())=="") return(invisible(NULL)) #if no text do nothing

   #display error if R fails at calculating
   tryCatch(
      if (gtkComboBoxGetActive(combobox)==0)
   result$setText((eval(parse(text=TextToCalculate$getText()))))
   else (result$setText(as.integer(eval(parse(text=TextToCalculate$getText()))))),
   error=function(e)
      {
      ErrorBox <- gtkDialogNewWithButtons("Error",window, "modal","gtk-ok", GtkResponseType["ok"])
      box1 <- gtkVBoxNew()
      box1$setBorderWidth(24)
      ErrorBox$getContentArea()$packStart(box1)

      box2 <- gtkHBoxNew()
      box1$packStart(box2)

      ErrorLabel <- gtkLabelNewWithMnemonic("There is something wrong with your text!")
      box2$packStart(ErrorLabel)
      response <- ErrorBox$run()


      if (response == GtkResponseType["ok"])
         ErrorBox$destroy()

      }
   )

}


  PasteSin<-function(button)
{
   TextToCalculate$setText(paste(TextToCalculate$getText(),"sin()",sep=""))

}

PasteCos<-function(button)
{
   TextToCalculate$setText(paste(TextToCalculate$getText(),"cos()",sep=""))

}

#however button variable was never used inside 
#functions, without it gSignalConnect would not work
gSignalConnect(Calculate, "clicked", DoCalculation)
gSignalConnect(Sin, "clicked", PasteSin)
gSignalConnect(Cos, "clicked", PasteCos)

Now it works like planned.

Also we get a nice error message.

Wiktor Ryciuk
[email protected]

To leave a comment for the author, please follow the link and comment on their blog: Rexamine » Blog/R-bloggers.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)