PyQt 中的线程和信号问题

发布于 2024-10-05 13:13:51 字数 1214 浏览 2 评论 0原文

我在 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'

I'm having some problems with communicating between Threads in PyQt. I'm using signals to communicate between two threads, a Sender and a Listener. The sender sends messages, which are expected to be received by the listener. However, no messages are receieved. Can anyone suggest what might be going wrong? I'm sure it must be something simple, but I've been looking around for hours and not found anything. Thanks in advance!

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'

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

北渚 2024-10-12 13:13:51

我不确定这是否是您所需要的,但它工作得很好......

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

I'm not sure if that is what you need, but it works fine...

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_()
故事与诗 2024-10-12 13:13:51

问题是 QThread 发送/接收信号,它需要运行一个 EventLoop。你不是,所以线程没有机会做出回应。查看此博客文章:你正在这样做错误

这是一个对我有用的示例 - 请注意,您需要在连接信号之前调用 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_())

The problem is that a QThread to send/receiver SIGNALS, it needs to be running an EventLoop. You aren't, so there is no opportunity to the thread to respond. Check out this blog post: You're doing it wrong

Here's an example that works for me - note the you need to call moveToThread BEFORE you connect the signals (this wasn't mentioned in the blog - not sure if it is specific to PyQt), otherwise they will run in the main thread.

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_())
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文