我的应用程序依赖于从两个不同的线程获取结果,如果线程结束,这两个线程会发送一个整数。我试图以这样的方式连接父类中的第三个函数,每次发出both信号时都会调用它。这些值存储在父类的队列中。
这是我想要实现的目标的最小工作示例。
self.number
用于跟踪函数调用。问题是,does_something 是为两个线程分别调用的,尽管它应该只调用一次并接收两个信号。我希望清楚地概述我的问题,非常感谢帮助。
需要注意的一件重要事情是,在我的应用程序中,工作线程包含一个持续运行以从相机收集数据的 while 循环。重要的是,这个循环不会终止,因此使用
.join()
不是一个选项,因为只要程序正在运行,工作线程就永远不会终止
# -*- coding: utf-8 -*-
from queue import Queue
import sys
from PyQt5 import QtCore as qtc
import numpy as np
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QLabel, QVBoxLayout, QWidget
class WorkerSignals(qtc.QObject):
finished = qtc.pyqtSignal()
error = qtc.pyqtSignal(int)
result = qtc.pyqtSignal(object)
class MainWindow(QMainWindow):
def __init__(self,*args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.threadpool = qtc.QThreadPool()
## number that checks number of function call
self.number = 0
self.queue_one = Queue()
self.queue_two = Queue()
self.setWindowTitle("Does something")
self. pagelayout = QVBoxLayout()
self.boxlayout = QVBoxLayout()
self.pagelayout.addLayout(self.boxlayout)
self.button = QPushButton("Does something")
self.lable = QLabel('Says something')
self.boxlayout.addWidget(self.button)
self.boxlayout.addWidget(self.lable)
# self.setCentralWidget(self.boxlayout)
self.button.clicked.connect(self.start_thread)
self.widget = QWidget()
self.widget.setLayout(self.pagelayout)
self.setCentralWidget(self.widget)
def start_thread(self):
worker_one = Emits_something(self.queue_one)
worker_two = Emits_something(self.queue_two)
worker_one.signals.finished.connect(self.does_something)
worker_two.signals.finished.connect(self.does_something)
self.threadpool.start(worker_one)
self.threadpool.start(worker_two)
def does_something(self):
print(self.number)
self.number +=1
if not self.queue_one.empty() and not self.queue_two.empty():
val_one = self.queue_one.get()
val_two = self.queue_two.get()
self.lable.setText(f"{val_one+val_two}")
class Emits_something(qtc.QRunnable):
def __init__(self,queue, *args,**kwargs):
super(Emits_something, self).__init__(*args, **kwargs)
self.signals = WorkerSignals()
self.queue = queue
@qtc.pyqtSlot()
def run(self):
val = np.random.randint(0,21)
self.queue.put(val)
self.signals.finished.emit()
if __name__ =='__main__':
app = QApplication(sys.argv)
w = MainWindow()
w.show()
app.exec_()
sys.exit(app.exec())
这个问题是通过问题本身来解决的。通过检查两个队列是否为空,代码可以仅在两个信号都发出各自的信号并且数据已存储在队列中时才触发显示。我将保留这个问题,希望其他人将来可以使用它。