# Playing with GUIs in R with RGtk2

June 16, 2014
By

(This article was first published on Rexamine » Blog/R-bloggers, and kindly contributed to R-bloggers)

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]