Tkinter RPy2 GUI问题

时间:2014-10-16 02:33:12

标签: python r user-interface tkinter rpy2

我在R中编写了一个tcltk gui,我希望使用R的“source”命令通过python实现。过去,这是一个简单的实现;我只是使用python中的RPy2来调用source命令,然后加载tcltk gui。

然而,现在看来情况并非如此。我意识到tkinter不是多线程的,这就是我的GUI现在冻结的原因。

为了解决这个问题,我试图在python中创建另一个线程(包含“source”命令),该线程充当另一个线程并使用队列函数。现在,来自R source命令的tcltk gui运行并且没有被冻结(因为它具有更新或刷新的能力,如果你愿意的话);但是,在无限循环中调用source命令会导致启动R Gui的多个实例。

有没有办法可以只调用一次源命令,但GUI是否能保持接受输入的能力?

这是迄今为止的代码,它改编自我发现的一个例子:

import Tkinter                                                                                                                                                                                                       
import time                                                                                                                                                                                                          
import threading                                                                                                                                                                                                     
import random                                                                                                                                                                                                        
import Queue                                                                                                                                                                                                         
import rpy2.robjects as robjects                                                                                                                                                                                     
from time import sleep                                                                                                                                                                                               

class GuiPart:                                                                                                                                                                                                       
    def __init__(self, master, queue):                                                                                                                                                                               
        self.queue = queue                                                                                                                                                                                           

    def processIncoming(self):                                                                                                                                                                                       
        while self.queue.qsize():                                                                                                                                                                                    
            try:                                                                                                                                                                                                     
                msg = self.queue.get(0)                                                                                                                                                                              
                print msg                                                                                                                                                                                            
            except Queue.Empty:                                                                                                                                                                                      
                pass                                                                                                                                                                                                 

class ThreadedClient:                                                                                                                                                                                                
    def __init__(self, master):                                                                                                                                                                                      
        self.master = master                                                                                                                                                                                         
        self.queue = Queue.Queue()                                                                                                                                                                                   
        self.gui = GuiPart(master, self.queue)                                                                                                                                                                       
        self.running = 1                                                                                                                                                                                             
        self.thread1 = threading.Thread(target=self.workerThread1)                                                                                                                                                   
        self.thread1.start()                                                                                                                                                                                         
        self.periodicCall()                                                                                                                                                                                          

    def periodicCall(self):                                                                                                                                                                                          
        self.gui.processIncoming()                                                                                                                                                                                   
        if not self.running:                                                                                                                                                                                         
            import sys                                                                                                                                                                                               
            sys.exit(1)                                                                                                                                                                                              
        self.master.after(100, self.periodicCall)                                                                                                                                                                    

    def workerThread1(self):                                                                                                                                                                                         
            while self.running == 1 :                                                                                                                                                                                
                rsource = robjects.r.source                                                                                                                                                                              
                rsource("biolab_gui_1.R")                                                                                                                                                                                



root = Tkinter.Tk()                                                                                                                                                                                                  

client = ThreadedClient(root)                                                                                                                                                                                        
root.mainloop()

0 个答案:

没有答案