Главное окно PyQt5 ждет, пока очередь не опустеет - PullRequest
0 голосов
/ 16 февраля 2020

Я создаю диспетчер задач с Qt, который запускает файл .py, когда устройства (в очереди) и некоторые параметры оба доступны .

Простой FIFO используется очередь python, а параметры вводятся пользователем в QDialog и отображаются в QtableWidget.

Вот мой код в упрощенной версии:

from PyQt5.QtCore import pyqtSignal, QThreadPool, QObject, QRunnable, pyqtSlot
from PyQt5.QtWidgets import QMainWindow,  QApplication
import sys
from queue import Queue


class WorkerSignals(QObject):
    error = pyqtSignal(tuple)
    released_device = pyqtSignal(object)

class Worker(QRunnable):
    def __init__(self, *args, **kwargs):
        super(Worker, self).__init__()
        self.using_device = arg
        self.params = kwarg

    @pyqtSlot()
    def run(self):
        try:
            # run the .py file on ith device
        except:
            # capture the error if .py encountered one
        finally:
            # send back the released device that has been used in this worker
            self.signals.released_device.emit(self.using_device)


class mainwindow_logic(QMainWindow, UI):
    def __init__(self, *args, **kwargs):
        QMainWindow.__init__(self, *args, **kwargs)
        self.setupUi(self)
        self.threadPool = QThreadPool()

        # init the device queue
        self.queue = Queue()
        for i in range(50):  #let's say there are 50 devices
            self.queue.put(i)

    def run(self):
        if not self.queue.empty() and self.params_not_None():
            # get the device id and set the worker
            _Worker = Worker(self.queue.get(), params=self.get_params())
            # start threading
            self.threadPool.start(_Worker)
            # slot of the finishing signal callback from the worker
            _Worker.signals.released_device.connect(self.enqueue)

    def loop_run(self):
        while True:
            self.start()

    def enqueue(self, device):
        self.queue.put(device)

    def get_params(self):
        # get the parameters

    def params_not_None(self):
        # check if there's params


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ui = mainwindow_logic(None)
    ui.show()
    sys.exit(app.exec_())

Метод run работает как шарм. Но когда я захочу l oop run методом loop, пользовательский интерфейс заклинивает, потому что while продолжает быстро зацикливаться.

Мой вопрос: есть ли в Qt подход Слушателя для приостановки l oop, когда очередь или параметры пусты?

...