我正在使用 gWidgets 工具包在使用 Rscript 运行的 R 脚本中创建 GUI。
创建 GUI 后,脚本退出。
我可以在脚本末尾使用 while(TRUE){Sys.sleep(9999)} 循环来防止这种情况,但这似乎很棘手。
有没有更好的方法告诉 R 仅在关闭 GUI 时退出,或者至少在构建 GUI 后进入 REPL?
我正在使用 gWidgets 工具包在使用 Rscript 运行的 R 脚本中创建 GUI。
创建 GUI 后,脚本退出。
我可以在脚本末尾使用 while(TRUE){Sys.sleep(9999)} 循环来防止这种情况,但这似乎很棘手。
有没有更好的方法告诉 R 仅在关闭 GUI 时退出,或者至少在构建 GUI 后进入 REPL?
您也许可以根据需要调整 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”工具包也是如此。它几乎使用了 Greg 建议的方法。
这个主题可能已经关闭,但作为 gwidgets 的新手,我遇到过。jverzani给出的解决方案显然是一个解决方案。我选择了另一个,没有使用任何补充对话框,只是因为我不想要一个,根本没有其他原因......
在 gwindow 的处理程序中,处理后我从环境中删除变量:
handler = function(h,...) {dispose(EDFAnalysis$w); rm(w,envir=EDFAnalysis)}
我的脚本的环境在哪里EDFAnalysis
......并且w
是主要的gwindow。
然后,在我的脚本的最后,我添加了:
while(exists("w",EDFAnalysis)){Sys.sleep(5)}
当然,可以使用小于 5 的值或更大的值。在我的情况下,5 秒就足够了,而且永远不会...... :-)
我发现,一个很好的方法是使用gtkMain()
RGtk2 库中的函数。这只是保持主循环运行直到gtkMainQuit()
被调用。
处理此问题的标准方法是请求用户输入以继续。这个单线就可以了。
编辑: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()
如果您使用的是tcltk
包而不是 gWidgets
那么您可以使用tkwait.window
函数 fromtcltk
告诉脚本等到 gui 窗口消失后再继续执行脚本。
为了完整性: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(),这会退出主“启动”脚本中的母进程。