我正在尝试为 R 包开发 GUI(使用 gWidgets)。我的计划是构建一个保存数据的主窗口,并使用按钮为每个函数调用小型 gui 包装器。不幸的是,我陷入了一个基本(?)问题——我不知道如何传输数据。
问题:
- 如何在单独的窗口之间正确发送数据?
- 如何从另一个窗口的处理程序中发送数据?
我的问题类似于: Loading and save variables in R with gWidgets,但从我读过的内容来看,不推荐使用 .GlobalEnv 。
我还看到有人使用 <<- 运算符:http: //www.mail-archive.com/r-sig-gui@r-project.org/msg00053.html,但我无法正确复制它(并且我认为它不适用于我的示例)。
下面是一个简单的示例,如果按下按钮,我尝试将文本发送到另一个窗口并再次返回。我已经尝试在处理程序中使用 return ,但这不起作用(也不确定是否允许)。在处理程序/内部函数可以对数据进行操作之前,子窗口会在函数结束时立即返回其值。我不知道如何从处理程序到达主窗口。
main <- function(){
library(gWidgets)
options(guiToolkit="RGtk2")
w <- gwindow(title="Main window",
visible=FALSE)
txt <- gtext(text="Initial text in main window.",
container=w)
btn <- gbutton("Send to sub window", container=w)
addHandlerChanged(btn, handler = function(h, ...) {
shouldbenew <- subwindow(svalue(txt))
svalue(txt) <- paste("The sub window immediately returns 'TRUE', before pushing 'Return to main':", shouldbenew )
} )
visible(w) <- TRUE
}
subwindow<- function(text){
library(gWidgets)
options(guiToolkit="RGtk2")
sw <- gwindow(title="Sub window",
visible=FALSE)
editedtxt <- gtext(text=paste(text, "- Text is transferred to the sub window, but I don't know how to send it back to the main window"),
container=sw)
btn <- gbutton("Send to main window", container=sw)
addHandlerChanged(btn, handler = function(h, ...) {
newtxt <- svalue(editedtxt)
return(newtxt)
} )
visible(sw) <- TRUE
}
更新: 这是我选择的解决方案(如 jverzani 建议的那样),使用上面的示例进行说明。我希望我正确理解了建议的解决方案,并且我已经以一种“不错”的方式实施了它,在 CRAN 中得到了理想的接受。
总而言之,我在主窗口环境中创建了一个新环境。我编辑了子窗口以获取通话中的环境。按下子窗口中的按钮assign
将编辑的文本传递给传递的环境。当子窗口关闭并且主窗口成为焦点时,可以使用get
.
main <- function(){
library(gWidgets)
options(guiToolkit="RGtk2")
# Create a new environment for passing data.
.mainGlobal <- new.env()
w <- gwindow(title="Main window", visible=FALSE)
txt <- gtext(text="Initial text in main window.",
container=w)
btn <- gbutton("Send to sub window", container=w)
addHandlerChanged(btn, handler = function(h, ...) {
# Call sub widget passing text and environment.
subwindow(text=svalue(txt), env=.mainGlobal)
} )
visible(w) <- TRUE
addHandlerFocus(w, handler = function (h, ...) {
if(exists("myText", envir=.mainGlobal)){
# Retrieve text and update.
svalue(txt) <- get("myText", envir=.mainGlobal)
}
})
}
subwindow<- function(text, env=NULL){
library(gWidgets)
options(guiToolkit="RGtk2")
sw <- gwindow(title="Sub window", visible=FALSE)
editedtxt <- gtext(text=text, container=sw)
btn <- gbutton("Send to main window", container=sw)
addHandlerChanged(btn, handler = function(h, ...) {
newtxt <- svalue(editedtxt)
assign("myText", newtxt, envir=env)
} )
visible(sw) <- TRUE
}