我正在尝试为R包开发GUI(使用gWidgets).我的计划是构建一个包含数据的主窗口,并使用按钮为每个函数调用小的gui包装器.不幸的是我遇到了一个基本的(?)问题 - 我不知道如何传输数据.
Questons:
我的问题类似于: 使用gWidgets在R中加载和保存变量,但是根据我的阅读,不推荐使用.GlobalEnv.
我也看到有人使用<< - 运算符:http://www.mail-archive.com/r-sig-gui@r-project.org/msg00053.html,但我无法正确地重现它(和我认为它不适用于我的例子.
下面是一个简单的例子,我尝试将文本发送到另一个窗口,如果按下按钮则再次返回.我已尝试在处理程序内返回,但这不起作用(也不确定是否允许).子窗口在处理程序/内部函数可以对数据执行操作之前立即在函数末尾返回其值.我不知道如何从处理程序到主窗口.
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
}
Run Code Online (Sandbox Code Playgroud)
更新: 这是我选择的解决方案(如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
}
Run Code Online (Sandbox Code Playgroud)
更好的方法是将GUI存储在引用类中,但需要对代码进行更大的重新处理.
setRefClass使用字段列表(每个窗口小部件一个)调用,并定义创建GUI的初始化方法.我通常创建一个函数来包装创建实例的调用.请参阅setRefClass代码块的末尾.
mainGui <- suppressWarnings(setRefClass( #Warnings about local assignment not relevant
"mainGui",
fields = list(
#widgets
w = "ANY", #"GWindow"
txt = "ANY", #"GEdit"
btn = "ANY" #"GButton"
),
methods = list(
initialize = function(windowPosition = c(0, 0))
{
"Creates the GUI"
w <<- gwindow(
"Main window",
visible = FALSE,
parent = windowPosition
)
txt <<- gedit(
"Initial text in main window.",
container = w
)
btn <<- gbutton(
"Send to sub window",
container = w
)
addHandlerChanged(
btn,
handler = function(h, ...) {
subWindow$setText(getText())
}
)
visible(w) <- TRUE
},
#other methods to access GUI functionality go here
getText = function()
{
svalue(txt)
},
setText = function(newTxt)
{
svalue(txt) <- newTxt
}
)
))
createMainGui <- function(...)
{
invisible(mainGui$new(...))
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3828 次 |
| 最近记录: |