I recently started using R and find myself blocked while trying to build a graphical user interface.
My aim is to code a GUI for the conduction of a survey. Basically, I would like to open a window composed of a question, an answer and a Next button. Upon cliking on Next I wish to save the answer and jump to the next window/question.
As I had problems opening several windows I looked here and found it was possible to open windows one after the other with the help of a handler:
addHandlerChanged() #upon the Next button
So I tried to input a code (see below) for two questions/windows. I thought to save the results in to_return: a matrix 2 rows (1, 2) and 3 columns (Question number, Question, Answer). [I am now trying to write answers question after question in an excel file]
My problem is as follows:
I fail to close the first window after opening the second (I tried adding dispose(h$obj) or visible(win1)=FALSE to the the first windows button handler but it fails)
I fail to "apend" data to my matrix (the to_return matrix is renewed with every window)
# calling GUI library
library(gWidgets)
options(guiToolkit="tcltk")
Q1 <- function(){
# creating first window
win1 <- gwindow("I) Q1.", visible=TRUE)
group <- ggroup(horizontal = FALSE, container=win1)
# creating question
question <- glabel("Do you have a driving license?", container = group)
# creating answer
answer <- gradio(c("Yes","No"), container=group)
# creating next button
nextQuestion <- gbutton("Next",container=group)
# handler
addHandlerChanged(nextQuestion, handler = function(h, ...) {
# answer to save in matrix
to_return <- rbind(to_return,c(svalue(win1),svalue(question),svalue(answer)))
#opening next question
Q2()
print(to_return)
} )
}
Q2<- function(){
# creating second window
win2 <- gwindow("I) Q2.", visible=TRUE)
group <- ggroup(horizontal = FALSE, container=win2)
# creating question
question <- glabel("What is your gender?", container = group)
# creating answer
answer <- gradio(c("Female","Male"), container=group)
# finish button
nextQuestion <- gbutton("Finish",container=group, handler = function(h,...) {
# answer to save in matrix
to_return <- rbind(to_return,c(svalue(win2),svalue(question),svalue(answer)))
print(to_return)
# finish and close
dispose(h$obj)
})
}
If I run Q1() I get the following results where to_return doens't keep the data...
[,1] [,2] [,3]
[1,] "I) Q1." "Do you have a driving license?" "Yes"
[,1] [,2] [,3]
[1,] "I) Q2." "What is your gender?" "Female"
Any help or insight will be greatly appreciated!
Thank you!
Octave
EDIT : Following the answer of jverzani, here is a possible code for two questions with data saving in csv file.
## calling GUI library
library(gWidgets)
options(guiToolkit="tcltk")
setwd("Your\\Path\\Here")
w <- gwindow(title="Survey")
g <- ggroup(cont=w)
state = new.env()
pages <- list()
pages[[1]] = function(cont, state) {
group <- ggroup(horizontal = FALSE, container=cont)
## creating question
question <- glabel("Do you have a driving license?", container = group)
## creating answer
answer <- gradio(c("Yes","No"), container=group)
## creating next button
nextQuestion <- gbutton("Next",container=group)
## handler
addHandlerChanged(nextQuestion, handler = function(h, ...) {
## answer to save in matrix
assign("A", c(svalue(question),svalue(answer)), state)
delete(cont, group)
pages[[2]](cont, state)
})
}
pages[[2]] = function(cont, state) {
group <- ggroup(horizontal = FALSE, container=cont)
## creating question
question <- glabel("What is your gender?", container = group)
## creating answer
answer <- gradio(c("Male","Female", "Other"), container=group)
## creating next button
nextQuestion <- gbutton("Next",container=group)
## handler
addHandlerChanged(nextQuestion, handler = function(h, ...) {
## answer to save in matrix
assign("B", c(svalue(question),svalue(answer)), state)
delete(cont, group)
pages[[3]](cont, state)
})
}
pages[[3]] = function(cont, state) {
group <- ggroup(horizontal=FALSE, container=cont)
## result matrix for csv
to_return=matrix(nrow=0,ncol=2)
colnames(to_return) <- c("Question", "Answer")
for (k in 1:length(names(state))) {
a = get(names(state)[k], state)
to_return <- rbind(to_return,a)
rownames(to_return)[k] <- paste("Q",k,sep = "")
g = ggroup(cont=group, horizontal=TRUE)
glabel(a[1], cont=g)
glabel(" ", cont=g)
glabel(a[2], cont=g)
}
btn <- gbutton("Finish", container=group, handler = function(h,...) {
write.csv(to_return, "survey.csv", row.names=TRUE, col.names=TRUE)
dispose(h$obj)})
}
## start it off
pages[[1]](g, state)
EDIT 2: the line assign("one", c(svalue(question),svalue(answer)), state) should use alphabetical letters ("A", "B"...) or numbers in the right order otherwise answers get mixed up when using for k in names(state).