【问题标题】:Threading and Signals problem in PyQtPyQt 中的线程和信号问题
【发布时间】:2017-03-09 00:47:20
【问题描述】:

我在 PyQt 中的线程之间进行通信时遇到了一些问题。我正在使用信号在两个线程之间进行通信,一个 Sender 和一个 Listener。发送者发送消息,这些消息预计会被侦听器接收。但是,没有收到任何消息。谁能建议可能出了什么问题?我敢肯定它一定很简单,但我已经四处寻找了几个小时,但没有找到任何东西。提前致谢!

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'

【问题讨论】:

  • Qt 决定向哪个线程发送信号取决于哪个线程创建了信号所在的对象实例。这意味着如果您从主线程创建一个 Listener 对象并向其发送信号,它将在主线程中调用它们。请记住,对象不是线程。参见例如ftp.qt.nokia.com/videos/DevDays2007/… 了解 Qt 中“线程关联”的详细信息。

标签: python multithreading pyqt signals


【解决方案1】:

我不确定这是否是您需要的,但它工作正常......

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

【讨论】:

    【解决方案2】:

    问题是一个 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_())
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-10
      • 2018-01-15
      • 1970-01-01
      • 2012-10-29
      • 2022-01-01
      • 2012-03-28
      • 1970-01-01
      相关资源
      最近更新 更多