R gWidgets2 не возвращает значения

Я пытаюсь сделать форму ввода с помощью gWidgets2, чтобы написать свое имя, выбрать период времени и выбрать автомобиль. Эти входные значения сохраняются в списке. Данные следующие:

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

Это мой код:

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)

Каким-то образом он возвращает пустой список. Если я не устанавливаю репортер, период и флот = NULL, это дает ошибку «репортер объекта не найден». Если я напишу это return(list(svalue(rep), svalue(per), svalue(car))) вместо return(list(reporter, period, vehicle)), он вернет значения по умолчанию.

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

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

[[3]]
[1] "car1"

как я могу вернуть эти входные значения?

РЕДАКТИРОВАТЬ: Моя интерпретация предложенного решения от @jverzani следующая:

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))
}

и/или:

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))
}

К сожалению, все те же проблемы.


person thban    schedule 20.04.2020    source источник


Ответы (1)


Вы не можете возвращать значения из обработчика (кроме модальных диалогов). Вам нужно их назначить. Обычно это делается с помощью <<- или среды, так что изменения в теле функции происходят за пределами тела. Например, в обработчике list.timeinterval вы можете написать e$period = ..., где e — это некоторая среда, которую вы инициализируете перед отображением графического интерфейса.

Ваше возвращаемое значение происходит мгновенно. Скорее вам нужно присвоить значения в обработчике чему-то постоянному. Вот один шаблон:

      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))
}

Когда вы взаимодействуете с диалонгом, среда e обновляется.

person jverzani    schedule 22.04.2020
comment
У меня ничего из этого не сработало: я заменил = на <<-, что привело к тем же результатам (например, period <<- svalue(per) в обработчике list.timeinterval. И я также попытался настроить новую среду: e <- new.env() перед отображением графического интерфейса и e$reporter <- svalue(rep) (пример time. интервальный обработчик), а затем return(list(e$reporter, e$period, e$fleets)) -> тот же результат - person thban; 24.04.2020
comment
Можете ли вы отредактировать свой пост, чтобы показать новый код с e$reporter и т. Д. Это должно работать, если собрано правильно. Скорее всего, это просто немного не так. - person jverzani; 25.04.2020