2

I am trying to make an input form with gWidgets2 to write your name, select a time period and select a car. These input values are the saved into a list. The data is following:

list.timeinterval = c("last month", "last year", "Specific Period")
list.vehicle = c("car1", "car2", "car3")

This is my code:

choose.specs <- function(list.timeinterval, list.vehicle){
  library(gWidgets2)
  library(gWidgets2tcltk)
  options(guiToolkit = "tcltk")

  reporter <- NULL
  period <- NULL
  vehicle <- NULL

  w <- gwindow("Choose report specification")
  g <- ggroup(horizontal = FALSE, cont = w)

  tmp <- gframe("Reporter name", cont = g, expand = TRUE)
  rep <- gedit("write your name",
               cont = tmp,
               handler = function(...)
                 reporter = svalue(rep))

  tmp <- gframe("Choose time intervall", cont = g, expand = TRUE)
  per <- gcombobox(list.timeinterval,
                   label = "Select time period",
                   editable = FALSE,
                   cont = tmp,
                   handler = function(...)
                     period = svalue(per))

  tmp <- gframe("Choose car", cont = g, expand = TRUE)
  car <- gcombobox(list.vehicle,
                   label = "Select car:",
                   editable = FALSE,
                   cont = tmp,
                   handler = function(...)
                     vehicle = svalue(car))

  visible(tmp, set = TRUE)

  btn <- gbutton("confirm", cont = g)

  addHandlerClicked(btn, handler = function(h,...) {
    dispose(w)
  })
  return(list(reporter,
              period,
              vehicle))
}

list.specs <- choose.specs(list.timeinterval, list.vehicle)

Somehow it returns an empty list. If i don't set reporter, period and fleet = NULL it gives an error "object reporter not found". If i write this return(list(svalue(rep), svalue(per), svalue(car))) instead of return(list(reporter, period, vehicle)) it returns the default values

[[1]]
[1] "write your name"

[[2]]
[1] "last month"

[[3]]
[1] "car1"

how can i return this input values?

EDIT: My interpretation of the suggested solution from @jverzani is following:

choose.specs <- function(list.timeinterval, list.vehicle){
  library(gWidgets2)
  library(gWidgets2tcltk)
  options(guiToolkit = "tcltk")


  reporter <- NULL
  period <- NULL
  fleets <- NULL

  e <- new.env()
  e$reporter <- reporter
  e$period <- period
  e$fleets <- fleets

  w <- gwindow("Choose report specification")
  g <- ggroup(horizontal = FALSE, cont = w)

  tmp <- gframe("Reporter name", cont = g, expand = TRUE)
  rep <- gedit("write your name",
               cont = tmp,
               handler = function(...)
                 e$reporter <- svalue(rep))

  tmp <- gframe("Choose time intervall", cont = g, expand = TRUE)
  per <- gcombobox(list.timeinterval,
                   label = "Select time period",
                   editable = FALSE,
                   cont = tmp,
                   handler = function(...)
                     e$period <- svalue(per))

  tmp <- gframe("Choose car", cont = g, expand = TRUE)
  car <- gcombobox(list.vehicle,
                   label = "Select car:",
                   editable = FALSE,
                   cont = tmp,
                   handler = function(...)
                     e$fleets <- svalue(car))

  visible(tmp, set = TRUE)

  btn <- gbutton("confirm", cont = g)

  addHandlerClicked(btn, handler = function(h,...) {
    dispose(w)
  })
  return(list(e$reporter,
              e$period,
              e$vehicle))
}

and/or:

choose.specs <- function(list.timeinterval, list.vehicle){
  library(gWidgets2)
  library(gWidgets2tcltk)
  options(guiToolkit = "tcltk")

  reporter <- NULL
  period <- NULL
  vehicle <- NULL

  w <- gwindow("Choose report specification")
  g <- ggroup(horizontal = FALSE, cont = w)

  tmp <- gframe("Reporter name", cont = g, expand = TRUE)
  rep <- gedit("write your name",
               cont = tmp,
               handler = function(...)
                 reporter <<- svalue(rep))

  tmp <- gframe("Choose time intervall", cont = g, expand = TRUE)
  per <- gcombobox(list.timeinterval,
                   label = "Select time period",
                   editable = FALSE,
                   cont = tmp,
                   handler = function(...)
                     period <<- svalue(per))

  tmp <- gframe("Choose car", cont = g, expand = TRUE)
  car <- gcombobox(list.vehicle,
                   label = "Select car:",
                   editable = FALSE,
                   cont = tmp,
                   handler = function(...)
                     vehicle <<- svalue(car))

  visible(tmp, set = TRUE)

  btn <- gbutton("confirm", cont = g)

  addHandlerClicked(btn, handler = function(h,...) {
    dispose(w)
  })
  return(list(reporter,
              period,
              vehicle))
}

Unfortunately still the same issues.

thban
  • 43
  • 5

1 Answers1

1

You can't return values from a handler (except for the modal dialogs). You need to assign them. Typically this is done with <<- or an environment, so that modifications within the function body happen outside the scope of the body. For example, in the list.timeinterval handler you might write e$period = ... where e is some environment you initialize before displaying the GUI.

Your return value happens instantly. Rather, you need to assign values in the handler to something persistent. Here is one pattern:

      library(gWidgets2)
  library(gWidgets2tcltk)
  options(guiToolkit = "tcltk")

e = new.env()
choose.specs <- function(e, list.timeinterval, list.vehicle){

  e$reporter <- NULL
  e$period <- NULL
  e$vehicle <- NULL

  w <- gwindow("Choose report specification")
  g <- ggroup(horizontal = FALSE, cont = w)

  tmp <- gframe("Reporter name", cont = g, expand = TRUE)
  rep <- gedit("write your name",
               cont = tmp,
               handler = function(...)
                 e$reporter <<- svalue(rep))

  tmp <- gframe("Choose time intervall", cont = g, expand = TRUE)
  per <- gcombobox(list.timeinterval,
                   label = "Select time period",
                   editable = FALSE,
                   cont = tmp,
                   handler = function(...)
                     e$period <<- svalue(per))

  tmp <- gframe("Choose car", cont = g, expand = TRUE)
  car <- gcombobox(list.vehicle,
                   label = "Select car:",
                   editable = FALSE,
                   cont = tmp,
                   handler = function(...)
                     e$vehicle <<- svalue(car))

  visible(tmp, set = TRUE)

  btn <- gbutton("confirm", cont = g)

  addHandlerClicked(btn, handler = function(h,...) {
    dispose(w)
  })
#  return(list(reporter,
#              period,
#              vehicle))
}

When you interact with the dialong, the e environment updates.

jverzani
  • 5,600
  • 2
  • 21
  • 17
  • Neither of this has worked for me: I replaced `=` with `<<-` which led to the same results (for example `period <<- svalue(per)` in the `list.timeinterval` handler. And i also tried to set up a new environment: `e <- new.env()` before displaying the GUI and `e$reporter <- svalue(rep)` (example time.interval handler) and then `return(list(e$reporter, e$period, e$fleets))` -> same results – thban Apr 24 '20 at 11:26
  • Can you edit your post to show the new code with e$reporter, etc. That should work if assembled properly. LIkely it is just off a bit. – jverzani Apr 25 '20 at 12:49