2014-02-11 112 views
3

我對pyqt非常陌生,所以我希望在我試圖做的事情中不會有什麼奇怪的。我試圖通過使用PyQt信號來創建QThreads之間的交互。特別是,我想要做的是從一個線程發出一個信號,這個信號應該中斷線程正在執行的特定方法。順便說一下,我遇到了一些問題,所以我想知道我想要做的是合法的。PyQt:qthread通過信號中斷

例如,現在我試圖做這樣的事情:

import sys 
import time 
from PyQt4 import QtGui as qt 
from PyQt4 import QtCore as qtcore 
from PyQt4.QtCore import QThread 
import threading 

app = qt.QApplication(sys.argv) 
class widget(qt.QWidget): 

    def __init__(self, parent=None): 
     qtcore.QObject.__init__(self) 


    def appinit(self): 
     self.mysignal = qtcore.SIGNAL("mysignal") 
     thread = mythread(self) 
     thread.start() 
     time.sleep(5) 
     print "before emit",str(threading.current_thread()) 
     self.emit(self.mysignal,"hello, I'm thread "+str(threading.current_thread())) 
     print "after emit",str(threading.current_thread()) 



class mythread(QThread): 
    def __init__(self,parent): 
     qtcore.QThread.__init__(self, parent=app) 
     self.parent=parent 

    def run(self): 
     self.mysignal = qtcore.SIGNAL("mysignal") 
     self.connect(self.parent, self.mysignal, self.myfunc) 
     for i in range(15): 
      print "**",threading.current_thread(),i 
      time.sleep(1) 

    def myfunc(self, msg): 
     print threading.current_thread(), msg, "Enter" 
     time.sleep(5) 
     print threading.current_thread(), msg, "Exit" 


def main(): 
    mywidget = widget() 
    mywidget.show() 
    qtcore.QTimer.singleShot(0, mywidget.appinit) 
    sys.exit(app.exec_()) 

main() 

我得到的輸出是:

** <_DummyThread(Dummy-1, started daemon 1968)> 0 
** <_DummyThread(Dummy-1, started daemon 1968)> 1 
** <_DummyThread(Dummy-1, started daemon 1968)> 2 
** <_DummyThread(Dummy-1, started daemon 1968)> 3 
** <_DummyThread(Dummy-1, started daemon 1968)> 4 
before emit <_MainThread(MainThread, started 2928)> 
<_MainThread(MainThread, started 2928)> hello, I'm thread <_MainThread(MainThread, started 2928)> Enter 
** <_DummyThread(Dummy-1, started daemon 1968)> 5 
** <_DummyThread(Dummy-1, started daemon 1968)> 6 
** <_DummyThread(Dummy-1, started daemon 1968)> 7 
** <_DummyThread(Dummy-1, started daemon 1968)> 8 
** <_DummyThread(Dummy-1, started daemon 1968)> 9 
<_MainThread(MainThread, started 2928)> hello, I'm thread <_MainThread(MainThread, started 2928)> Exit 
after emit <_MainThread(MainThread, started 2928)> 
** <_DummyThread(Dummy-1, started daemon 1968)> 10 
** <_DummyThread(Dummy-1, started daemon 1968)> 11 
** <_DummyThread(Dummy-1, started daemon 1968)> 12 
** <_DummyThread(Dummy-1, started daemon 1968)> 13 
** <_DummyThread(Dummy-1, started daemon 1968)> 14 

我實際上已經預期MyThread的中斷其執行和運行MYFUNC。順便說一下,mythread不會中斷它的執行,myfunc函數實際上是由主線程運行的。我試圖做相反的處理(生成的線程向主線程發送一個信號),它工作。

我想我還沒有完全理解信號是如何工作的,以及是否可以做我想做的事情。有關於此的任何線索?我在網上尋找解決方案,但沒有結果。

感謝

+2

中斷像經由信號長時間運行循環同步代碼將不起作用:跨線程信號/時隙需要在接收線程的事件循環(即,它必須輸入在run()中,通過調用exec());要調用槽,接收線程必須返回到事件循環;即如果你有一個長時間運行的循環,事件循環將被阻塞,並且該槽不會被調用。 –

+0

我想我現在開始理解得更好了。順便說一下,我用app.exec_()替換了mythread.run()中的for循環。結果是函數myfunc仍然被主線程調用,所以我覺得別的是錯的。 – Cell

回答

0

好了,從我能明白的是,你想要的線程進入5秒入睡前進一步迭代。

import sys 
import time 
from PyQt4 import QtGui as qt 
from PyQt4 import QtCore as qtcore 
from PyQt4.QtCore import QThread 
import threading 

app = qt.QApplication(sys.argv) 
class widget(qt.QWidget): 

    def __init__(self, parent=None): 
     qtcore.QObject.__init__(self) 


    def appinit(self): 
     self.mysignal = qtcore.SIGNAL("mysignal") 
     thread = mythread(self,self.mysignal) 
     thread.start() 
     time.sleep(5) 
     print "before emit",str(threading.current_thread()) 
     self.emit(self.mysignal,"hello, I'm thread "+str(threading.current_thread())) 
     print "after emit",str(threading.current_thread()) 



class mythread(QThread): 
    def __init__(self,parent,sig): 
     qtcore.QThread.__init__(self, parent=app) 
     self.parent=parent 
     self.mysignal = sig 
     self.stop_event=threading.Event() 
     self.connect(self.parent, self.mysignal, self.setIt) 

    def run(self): 

     for i in range(15): 
      if self.stop_event.isSet(): 
       self.myfunc() 
      print "**",threading.current_thread(),i 
      time.sleep(1) 

    def setIt(self,msg): 
     self.stop_event.set() 
     self.msg = msg 

    def myfunc(self): 
     print threading.current_thread(),self.msg , "Enter" 
     time.sleep(5) 
     print threading.current_thread(),self.msg , "Exit" 
     self.stop_event.clear() 


def main(): 
    mywidget = widget() 
    mywidget.show() 
    qtcore.QTimer.singleShot(0, mywidget.appinit) 
    sys.exit(app.exec_()) 

main() 

輸出:

** <_DummyThread(Dummy-1, started daemon 7312)> 0 
** <_DummyThread(Dummy-1, started daemon 7312)> 1 
** <_DummyThread(Dummy-1, started daemon 7312)> 2 
** <_DummyThread(Dummy-1, started daemon 7312)> 3 
** <_DummyThread(Dummy-1, started daemon 7312)> 4 
before emit <_MainThread(MainThread, started 232)> 
after emit <_MainThread(MainThread, started 232)> 
<_DummyThread(Dummy-1, started daemon 7312)> hello, I'm thread <_MainThread(MainThread,  started 232)> Enter 
<_DummyThread(Dummy-1, started daemon 7312)> hello, I'm thread <_MainThread(MainThread,  started 232)> Exit 
** <_DummyThread(Dummy-1, started daemon 7312)> 5 
** <_DummyThread(Dummy-1, started daemon 7312)> 6 
** <_DummyThread(Dummy-1, started daemon 7312)> 7 
** <_DummyThread(Dummy-1, started daemon 7312)> 8 
** <_DummyThread(Dummy-1, started daemon 7312)> 9 
** <_DummyThread(Dummy-1, started daemon 7312)> 10 
** <_DummyThread(Dummy-1, started daemon 7312)> 11 
** <_DummyThread(Dummy-1, started daemon 7312)> 12 
** <_DummyThread(Dummy-1, started daemon 7312)> 13 
** <_DummyThread(Dummy-1, started daemon 7312)> 14