2015-03-24 106 views
0

我需要制作一个图形应用程序,用于从控制台读取数据以更新某些小部件,这需要2个线程,一个用于GUI,一个用于控制台。问题是raw_input函数不起作用,也冻结了应用程序。这是代码。在pygtk应用程序上运行raw_input

import pygtk 
pygtk.require('2.0') 
import gtk 
import gobject 
from time import sleep 
import sys 
import threading 

class Worker (threading.Thread): 
    def __init__(self, app): 
     threading.Thread.__init__(self) 
     self.app = app 

    def run(self): 
     text = raw_input("Enter some text: ") #It freezes the application 
     #text = "Hola" #It Works 
     self.app.writeMessage(text, False) 

class Application: 
    def __init__(self, title, xPos, yPos): 
     gtk.threads_init() 
     self.win = gtk.Window() 
     screen = self.win.get_screen() 
     screenW = screen.get_width() 
     screenH = screen.get_height() 
     windowW = int(screenW * 0.5) 
     windowH = int(screenH * 0.25) 
     if type(xPos) is float: 
      xPos = int(screenW * xPos) 
     if type(yPos) is float: 
      yPos = int(screenH * yPos) 

     self.messageArea = gtk.TextView() 
     self.scroll = gtk.ScrolledWindow() 
     self.scroll.add(self.messageArea) 
     self.win.set_size_request(windowW, windowH) 
     self.win.set_title(title) 
     self.win.add(self.scroll) 
     self.win.show_all() 
     self.win.move(xPos, yPos) 
     self.win.connect("destroy", gtk.mainquit) 


    def doOperation(self, function, *args, **kw): 
     def idle_func(): 
      try: 
       gtk.threads_enter() 
       function(*args, **kw) 
       return False 
      finally: 
       gtk.threads_leave() 
     gobject.idle_add(idle_func) 

    def sleeper(): 
     time.sleep(.001) 
     return 1 # don't forget this otherwise the timeout will be removed 

    def mainloop(self): 
     #Trick for running threads and pygtk on win32 enviroment 
     if sys.platform == 'win32': 
      gtk.timeout_add(400, self.sleeper) 
     gtk.threads_enter() 
     gtk.mainloop() 
     gtk.threads_leave() 


    def writeMessage(self, message, isMainThread): 
     if isMainThread: 
      buf = self.messageArea.get_buffer() 
      end_iter = buf.get_end_iter() 
      buf.insert(end_iter, message) 
     else:   
      self.doOperation(self.writeMessage, message, True) 


if __name__ == "__main__": 
    app = Application("Hello", 0, 0) 
    worker = Worker(app) 
    app.doOperation(worker.start) 
    app.mainloop() 

奇怪的代码,如果你在Eclipse中的PyDev运行它才能正常运行,但它不会是有意的,我必须从控制台运行它。所以这是一个问题,如何在单独的线程上执行raw_input函数和GUI?

回答

0

take a look at this。它解释了python中没有事件循环支持,你可以在导入它后禁用pygtk事件循环。

+0

这对我很有用,但我不知道我是否正确地做。我在代码的开头添加了一行“gtk.set_interactive(False)”,并在Windows和Linux操作系统中测试了该程序。对不起英文,我只会说西班牙语 – user3155832 2015-03-25 04:00:53

相关问题