PyQt跨线程发出信号
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PyQt跨线程发出信号相关的知识,希望对你有一定的参考价值。
我一直在搞乱PyQt和跨线程的信号/插槽。在这种情况下,我找不到我的错误:
我有一个类(MultipleProcessLauncher),它能够在不同的线程中启动多个进程。我捕获每个进程的stdout并将这些消息发送到另一个线程(OutputWorker)读取的单个队列,这个最后一个线程应该发送一个信号onNewMessage(我认为它没有)捕获主类但是回调函数永远不会被称为。
- 进程线程使用消息填充队列
- 阅读线程捕获所有这些消息(我可以在while循环中使用
print(item)
打印它们)
但是: - 读取线程的信号似乎没有发出任何内容,因此主线程的回调函数永远不会被调用...
非常感谢你的帮助,我想我错过了一些有交叉线程信号的东西......
class OutputWorker(QObject):
onNewMessage = pyqtSignal(['QString'])
def __init__(self, queue, parent=None):
super(OutputWorker, self).__init__(parent)
self.queue = queue
def work(self):
while True:
item = self.queue.get()
self.onNewMessage.emit(item)
self.queue.task_done()
class MultipleProcessLauncher(QObject):
commandEvent = pyqtSignal(['QString'])
def __init__(self, parent=None):
super(MultipleProcessLauncher, self).__init__(parent)
self.messaging_queue = Queue()
# Start reading message
self.reading_thread = QThread()
self.worker = OutputWorker(self.messaging_queue)
self.worker.moveToThread(self.reading_thread)
self.worker.onNewMessage.connect(self.command_event)
self.reading_thread.started.connect(self.worker.work)
self.reading_thread.start()
def execute(self, command):
p = subprocess.Popen(command, stdout=subprocess.PIPE)
t = Thread(target=self.enqueue, args=(p.stdout, self.messaging_queue))
t.daemon = True
t.start()
def enqueue(self, stdout, queue):
for line in iter(stdout.readline, b''):
queue.put(line.decode())
stdout.close()
def command_event(self, event):
# This point is never reached
print('message received')
if __name__ == '__main__':
manager = MultipleProcessLauncher()
manager.execute('ipconfig')
time.sleep(100)
答案
Qt的跨线程信令基于事件循环,因此您需要执行QApplication,以便有一个主事件循环来处理来自其他线程的信号。例如:
if __name__ == '__main__':
app = QApplication([])
manager = MultipleProcessLauncher()
manager.execute('ipconfig')
MAX_WAIT_MSEC = 100 * 1000 # 100 seconds
QTimer.singleShot(MAX_WAIT_MSEC, app.quit)
app.exec()
在您的实际应用程序中,您可能会根据用户输入执行管理器,因此执行将在一个插槽中,并且不需要退出等,但您明白了。
以上是关于PyQt跨线程发出信号的主要内容,如果未能解决你的问题,请参考以下文章