Как остановить завершение скрипта R gWidgets

Я использую набор инструментов gWidgets для создания графического интерфейса в R-скрипте, который запускается с использованием Rscript.

Когда графический интерфейс создан, скрипт завершает работу.

Я могу предотвратить это с помощью цикла while(TRUE){Sys.sleep(9999)} в конце скрипта, но это кажется хакерским.

Есть ли лучший способ сказать R выйти только тогда, когда графический интерфейс закрыт, или, по крайней мере, войти в REPL после создания графического интерфейса?


person Rob Myers    schedule 23.10.2011    source источник
comment
По сути, это тот же вопрос: stackoverflow.com/questions/7835947/   -  person Dirk Eddelbuettel    schedule 24.10.2011
comment
Верно, Дирк, но ответ на этот вопрос немного не ясен.   -  person Dieter Menne    schedule 24.10.2011
comment
Да, я не видел этот вопрос, но я не думаю, что это поможет, поскольку я уже делаю одну из вещей, которые они предлагают. Там также это, но опять же это немного хакерский - r-from-immediately-exi" title="как предоставить выражение для r из командной строки, но немедленно остановить r из exi"> stackoverflow.com/questions/7695177/   -  person Rob Myers    schedule 24.10.2011


Ответы (6)


Возможно, вы сможете адаптировать gbasicdialog для своих нужд. Этот конструктор создает модальный контейнер, из которого вы можете создавать другие окна. Вот пример:

library(gWidgets)
options(guiToolkit="RGtk2")
require(fortunes)                       # just for fun

hold_it <- gbasicdialog(do.buttons=FALSE)
b <- gbutton("click me for a message", cont=hold_it, handler=function(h,...) {
  gmessage(paste(fortune(), collapse="\n"), parent=hold_it)
})
visible(hold_it, TRUE)

То же самое работает с набором инструментов "tcltk". Он использует в значительной степени то, что, по мнению Грега, можно сделать.

person jverzani    schedule 25.10.2011
comment
Действительно полезно и весело....littler + gWidgets рулит. Не могу дождаться, чтобы прочитать вашу новую книгу о программировании с графическим интерфейсом!! - person dickoa; 06.11.2011

Эта тема может быть закрыта, но я, как новичок в gwidgets, столкнулся с этим. Решение, данное jverzani, очевидно, является решением. Я выбрал другой, не используя никакого дополнительного диалога, просто потому, что он мне не нужен, безо всякой другой причины...

В обработчике gwindow после удаления удаляю переменную из окружения:

handler = function(h,...) {dispose(EDFAnalysis$w); rm(w,envir=EDFAnalysis)}

где EDFAnalysis — среда моего скрипта... а w — главное окно.

Затем в конце моего скрипта я добавил:

while(exists("w",EDFAnalysis)){Sys.sleep(5)}

конечно, можно использовать меньшее значение, чем 5, или большее значение. В моем случае достаточно 5 с и не навсегда... :-)

person ffeschet    schedule 19.11.2013

Стандартный способ справиться с этим — запросить ввод данных пользователем для продолжения. Этот однострочник сделает свое дело.

РЕДАКТИРОВАТЬ: readline работает только при интерактивном использовании, поэтому я заменил его на scan, что немного менее красиво.

pause_for_input <- function()
{
  message("Press ENTER to continue")
  invisible(scan(n = 0, quiet = TRUE))
}

Итак, ваш скрипт должен выглядеть так

#Create you GUI
#Whatever else
pause_for_input()
person Richie Cotton    schedule 24.10.2011
comment
Хм. На самом деле, прочитав документацию для readline, я не уверен, будет ли работать с littler. Может кто-нибудь проверить, пожалуйста? - person Richie Cotton; 24.10.2011

Если вы используете пакет tcltk вместо gWidgets, вы могли бы использовать функцию tkwait.window из tcltk, чтобы указать скрипту ждать, пока окно графического интерфейса не исчезнет, ​​прежде чем продолжить скрипт.

person Greg Snow    schedule 24.10.2011
comment
Я использую пакет Gtk, но это только из-за знакомства. - person Rob Myers; 24.10.2011
comment
Зависит ли Gtk от tcltk? если это так, то может применяться то же решение, в противном случае посмотрите, есть ли в Gtk аналогичная функция, которая ожидает события в графическом интерфейсе. - person Greg Snow; 24.10.2011

Я обнаружил, что хороший способ сделать это — использовать функцию gtkMain() в библиотеке RGtk2. Это просто поддерживает выполнение основного цикла до тех пор, пока не будет вызван gtkMainQuit().

person ozjimbob    schedule 10.12.2012
comment
Как бы вы его использовали? (документация не такая уж и разговорчивая) - person AdrieanKhisbe; 09.09.2013

Для полноты: ozjimbob уже дал ответ на наиболее «чистый» способ, как это сделать. Ответ ffeschet у меня не сработал ни на Unix, ни на Windows.

Следовательно, в основном «запускающем» сценарии у вас должны быть хотя бы эти записи:

options("guiToolkit"="RGtk2")
library(RGtk2)
library(gWidgets)
library(gWidgetsRGtk2)
StartMyGUI()
gtkMain()

В «дочернем» процессе «StartMyGUI()» ваш код может, например. выглядеть так:

StartMyGUI <- function(handler=function(h,...) {
        dispose(h$obj)
    }) {

window <- gwindow("Hello")
group <- ggroup(container = window)
glabel("Hello World!", container=group, expand=TRUE)

# A group to organize the buttons
button.group <- ggroup(container = group)
# Push buttons to right
addSpring(button.group)
gbutton("OK", handler=handler, container=button.group)
gbutton("Cancel", handler = function(h,...) {
            dispose(window)
            gtkMainQuit()
        },
        container=button.group)

return()
} 

Только когда пользователь нажимает кнопку «Отмена», вызывается gtkMainQuit(), который выходит из материнского процесса в основном «запускающем» сценарии.

person GrauBernden    schedule 13.11.2014