Я пытаюсь реализовать приложение Qt для чтения данных с инструмента и непрерывного построения графика с использованием PyQt5. У меня все работает, но в настоящее время я вызываю функцию в главном окне для проверки, должен ли рабочий QRunnable продолжать чтение или нет. Это кажется немного отрывочным, поскольку они работают в разных потоках. В Интернете довольно много ссылок о том, что QRunnables может отправлять и получать сигналы и что они предпочтительнее при использовании QThreadPool и QRunnable.
Ниже приведен пример моего решения для простого секундомера ( Да, я знаю, что это ужасный секундомер, который будет отображать любое время обработки как ошибку, но суть в том, чтобы просто показать мою проблему):
import sys
import time
from PyQt5 import QtWidgets
from PyQt5.QtCore import pyqtSlot, pyqtSignal, QRunnable, QThreadPool, QObject
from ui_stopwatch import Ui_MainWindow
class WorkerSignals(QObject):
result = pyqtSignal(int)
finished = pyqtSignal()
class Worker(QRunnable):
def __init__(self, parent, count):
super(Worker, self).__init__()
self.signals = WorkerSignals()
self.parent = parent
self.count = count
self.continue_counting = True
@pyqtSlot()
def run(self):
while self.continue_counting:
time.sleep(1)
self.count += 1
self.signals.result.emit(self.count)
self.continue_counting = self.parent.get_counting_state()
self.signals.finished.emit()
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setupUi(self)
self.thread_pool = QThreadPool()
self.bt_start.clicked.connect(self.start)
self.bt_stop.clicked.connect(self.stop)
self.counting_state = False
self.count = 0
def get_counting_state(self):
return self.counting_state
@pyqtSlot()
def start(self):
self.bt_start.setEnabled(False)
self.counting_state = True
worker = Worker(self, self.count)
worker.signals.result.connect(self.update_time)
worker.signals.finished.connect(self.enable_start)
self.thread_pool.start(worker)
self.bt_stop.setEnabled(True)
@pyqtSlot()
def stop(self):
self.counting_state = False
self.bt_stop.setEnabled(False)
@pyqtSlot(int)
def update_time(self, value):
self.count = value
self.label_output.setText(str(self.count))
@pyqtSlot()
def enable_start(self):
self.bt_start.setEnabled(True)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
Мой вопрос: как бы я изменил это вместо вызова функции get_counting_state()
использовать сигнал из главного окна? Или мой подход с вызовом функции в порядке?
Я пропустил файл ui_stopwatch.py
, который является просто файлом конструктора с двумя кнопками (bt_start
и bt_stop
) и меткой (label_output
) ) но просто дайте мне знать, если вы хотите, чтобы я также добавил этот код.