2010-12-01 24 views
5

PyQtのスレッド間の通信に問題があります。私は2つのスレッドSenderとListenerの間で通信するためにシグナルを使用しています。送信者は、リスナーが受信すると予想されるメッセージを送信します。ただし、メッセージは受信されません。誰が何が間違っているかもしれないと示唆することができます私はそれが何かシンプルでなければならないと確信していますが、何時間も探していて何も見つけられませんでした。前もって感謝します!PyQtのスレッディングとシグナルの問題

from PyQt4 import QtCore,QtGui 
import time 

class Listener(QtCore.QThread):  
    def __init__(self): 
     super(Listener,self).__init__() 

    def run(self): 
     # just stay alive, waiting for messages 
     print 'Listener started' 
     while True: 
      print '...' 
      time.sleep(2) 

    def say_hello(self): 
     print ' --> Receiver: Hello World!' 

class Sender(QtCore.QThread): 
    # a signal with no arguments 
    signal = QtCore.pyqtSignal() 

    def __init__(self): 
     super(Sender,self).__init__() 
     # create and start a listener 
     self.listener = Listener() 
     self.listener.start() 
     # connect up the signal 
     self.signal.connect(self.listener.say_hello) 
     # start this thread 
     self.start() 

    def run(self): 
     print 'Sender starting' 
     # send five signals 
     for i in range(5): 
      print 'Sender -->' 
      self.signal.emit() 
      time.sleep(2) 
     # the sender's work is done 
     print 'Sender finished' 
+0

Qtは、信号が入っているオブジェクトのインスタンスを作成したスレッドに依存して信号を送信するためにどのスレッドを決定します。あなたのメインスレッドからリスナーオブジェクトを作成し、それに信号を送信する場合、それは彼らを呼び出します意味メインスレッドでオブジェクトはスレッドではないことを忘れないでください。例えば、 Qtの「スレッドアフィニティ」の詳細については、ftp://ftp.qt.nokia.com/videos/DevDays2007/DevDays2007%20-%20Multi-threading_in_Qt.pdfを参照してください。 –

答えて

5

from PyQt4 import QtCore,QtGui 
import time 

class Listener(QtCore.QThread): 
    def __init__(self): 
     super(Listener,self).__init__() 

    def run(self): 
     print('listener: started') 
     while True: 
      time.sleep(2) 

    def connect_slots(self, sender): 
     self.connect(sender, QtCore.SIGNAL('testsignal'), self.say_hello) 

    def say_hello(self): 
     print('listener: received signal') 

class Sender(QtCore.QThread): 
    def __init__(self): 
     super(Sender,self).__init__() 

    def run(self): 
     for i in range(5): 
      print('sender: sending signal') 
      self.emit(QtCore.SIGNAL('testsignal')) 
      time.sleep(2) 
     print('sender: finished') 

if __name__ == '__main__': 
    o_qapplication = QtGui.QApplication([]) 
    my_listener = Listener() 
    my_sender = Sender() 
    my_listener.connect_slots(my_sender) 
    my_listener.start() 
    my_sender.start() 
    i_out = o_qapplication.exec_() 
4

問題はQThreadは/レシーバ信号を送信することである...それは何が必要である場合、私はわからないんだけど、それが正常に動作し、それが実行されている必要がありEventLoop。そうではないので、スレッドが応答する機会はありません。 You're doing it wrong

ここでは私のために動作する例があります - 信号を接続する前にmoveToThreadを呼び出す必要があることに注意してください(これはブログでは言及されていません - PyQtに固有のものかどうかはわかりません)それ以外の場合は、メインスレッドで実行されます。

import sys 
from PyQt4.QtCore import * 
from PyQt4.QtGui import * 
import time 

class MyThread(QThread): 
    def __init__(self, name): 
     super(MyThread, self).__init__() 
     self.setObjectName(name) 

    def run(self): 
     print "RUN", QThread.currentThread().objectName(), QApplication.instance().thread().objectName() 
     self.exec_() 
     print "RUN DONE", QThread.currentThread().objectName() 

class Producer(QObject): 
    def __init__(self, parent=None): 
     super(Producer, self).__init__(parent) 

    def Start(self): 
     for i in range(5): 
      print "Producer",i,QThread.currentThread().objectName() 
      self.emit(SIGNAL("testsignal"),i) 
      time.sleep(2) 
     time.sleep(1) 
     qApp.quit() 

class Consumer(QObject): 
    def __init__(self, parent=None): 
     super(Consumer, self).__init__(parent) 

    def Consume(self, i): 
     print "Consumed",i,QThread.currentThread().objectName() 

if __name__ == "__main__": 
    app = QApplication([]) 
    producer = Producer() 
    consumer = Consumer() 
    QThread.currentThread().setObjectName("MAIN") 
    producerThread = MyThread("producer") 
    consumerThread = MyThread("consumer") 
    producer.moveToThread(producerThread) 
    consumer.moveToThread(consumerThread) 
    producerThread.started.connect(producer.Start) 
    producer.connect(producer, SIGNAL("testsignal"), consumer.Consume) 
    def aboutToQuit(): 
     producerThread.quit() 
     consumerThread.quit() 
     time.sleep(1) 
    qApp.aboutToQuit.connect(aboutToQuit) 
    consumerThread.start() 
    time.sleep(.1) 
    producerThread.start() 
    sys.exit(app.exec_()) 
関連する問題