2010-12-01 16 views
5

PyQt içinde Konular arasında iletişim kurma konusunda bazı sorunlar yaşıyorum. İki iş parçacığı, Gönderen ve Dinleyici arasında iletişim kurmak için sinyaller kullanıyorum. Gönderen, dinleyici tarafından alınması beklenen mesajları gönderir. Ancak, hiçbir mesaj alınmaz. Neyin yanlış gidebileceğini öneren var mı? Eminim basit bir şey olmalı, ama saatlerce etrafa baktım ve bir şey bulamadım. Şimdiden teşekkürler!Threading ve Signals sorunu

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 sinyal olduğunu nesne örneğini oluşturdu hangi iplik bağlı bir sinyal göndermek için hangi diş karar verir. Eğer ana iş parçacığı bir Dinleyici nesnesi oluşturmak ve buna sinyaller gönderir eğer Anlamı, bunları çağırmak edeceğiz ana iş parçacığında. Unutmayın, nesne iplik değildir. Bakınız örn. Qt. "iş parçacığı afinitesi" ile ilgili ayrıntılar için ftp://ftp.qt.nokia.com/videos/DevDays2007/DevDays2007%20-%20Multi-threading_in_Qt.pdf. –

cevap

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

sorun QThread/alıcı İŞARETLERİ göndermek olmasıdır ... bu neye ihtiyacınız olup olmadığından emin değilim ama iyi çalışıyor, bu çalıştırıyor olması gerekir bir EventLoop. Öyle değilsiniz, dolayısıyla iş parçacığının yanıt vermesi için bir fırsat yok. Bu blog gönderisine bir göz atın: You're doing it wrong

İşte benim için çalışan bir örnek - MoveToThread'i çağırmanız gerektiğini unutmayın ÖNCE sinyalleri bağladığınızdan önce (bu blogda belirtilmemişti - PyQt'ye özgü olup olmadığından emin değil) aksi takdirde ana iş parçacığında çalışırlar.

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_())