Rktk2中的gtkProgressBar

时间:2010-09-29 09:42:27

标签: r gtk progress-bar

我正在尝试将gtkProgressBar添加到我为R脚本创建的一个小接口(使用RGtk2包)。

如果我做一些简单的事情,如:

for (i in 1:50)
    {
    gtkProgressBarSetFraction(progress, i/50)
    Sys.sleep(1)
    }

一切都顺利进行,每秒都会更新一次。

然而,当我转到我的实际代码时,我有一个循环,我在其中执行类似

的操作
for(i in 1:1000)
    {
    gtkProgressBarSetFraction(progress, i/1000)
    #do some heavy computation here
    }

这里的问题是界面“冻结”并且进度条仅在循环结束时更新,因此完全无法使用...

我在这里遗漏了什么吗?如何定期“唤醒”界面以便刷新?

谢谢 尼科

编辑:好的,我解决了问题,但我仍然不明白发生了什么。我在Sys.sleep之后添加了gtkProgressBarSetFraction来电,现在界面更新了。为了减少“浪费的时间”,我刚刚做了Sys.sleep(0.0001)(因此,对于1000个周期,我只有大约0.1-1s的计算时间,这是可以接受的)。任何人都可以解释为什么会这样?

2 个答案:

答案 0 :(得分:6)

处理一个事件:gtkMainIterationDo(FALSE)。处理所有待处理事件:while(gtkEventsPending()) gtkMainIteration()

由于R和Gtk事件循环交互的方式,需要此代码 - 在每个点上,R或Gtk处于控制之中,并且需要手动将控制权移交给另一个。 Sys.sleep是这样做的一种方式,这些RGtk2特定功能是另一种。

答案 1 :(得分:2)

几乎所有的GUI都是使用称为事件循环的概念制作的。该程序具有一些消息队列,并且在从队列中挑选新消息并执行它们的过程中本身无限循环。队列由从OS接收的一些事件填充,例如击键,鼠标点击,调整窗口大小等,以及程序本身抛出的消息。 它看起来不像这样,但R也有自己的事件循环(对于图形,但不仅如此,它在某种程度上被RGtk扩展,虽然它通常很复杂,但我不会详细介绍)。
现在,当您调用gtkProgressBarSetFraction时,进度条不会直接更新,但会创建一条请求重绘的消息并将其推送到队列中。因此,它将在事件循环迭代中被选中之前没有任何效果,但是这将不会发生,直到R完成脚本的执行或者异常激活循环(通过内部超时或某些函数,如Sys.sleep())。