2015-03-24 72 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