我想爲R包開發一個GUI(使用gWidgets)。我的計劃是構建一個包含數據的主窗口,並使用按鈕調用每個函數的小型gui包裝。不幸的是我被困在一個基本的(?)問題 - 我不知道如何傳輸數據。如何從gWidgets和處理程序返回值?
Questons:
- 如何正確單獨的窗口之間發送數據?
- 如何從另一個窗口中的處理程序發送數據?
我的問題是相似的: Loading and saving variables in R with gWidgets,但是從我已閱讀使用.GlobalEnv不推薦。
我也看到有人使用< < - operator:http://www.mail-archive.com/[email protected]/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
}
更新: 這裏是我挑選作爲前進的方向(由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
}
最簡單的事情是使用全局變量要小部件修改。或者,您可以將變量放入環境中。正如他們所定義的,他們坐在兩個功能的環境中,所以兩者不能溝通。 – jverzani 2013-03-17 02:16:55
感謝您的建議!我如何以不會冒險覆蓋工作區中任何現有對象的方式使用全局變量(並且被提交給CRAN的包所接受)?我將不勝感激,如果有人可以通過修改上面的示例顯示正確的方式。 – 2013-03-17 07:44:50