简体   繁体   中英

R gWidgets2 doesn't return values

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM