在Python中为不同的worker重用QThread

问题描述 投票:0回答:1

我想对不同的工作人员使用相同的 QThread。也就是说,首先

worker1
被传递到线程并运行。完成后,
worker2
应该传递给线程并运行。

所以,这是我的尝试

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QAction
from PyQt5 import uic
from PyQt5.QtCore import QObject, QThread, pyqtSignal
from time import sleep

class MainWin(QtWidgets.QMainWindow):
   def __init__(self):
      QtWidgets.QMainWindow.__init__(self)
      self.thread = QThread()
      self.worker1 = Worker1()
      self.worker1.finished.connect(self.w1_finish)
      self.thread.started.connect(self.worker.run)
      self.thread.start()
   
   def w1_finish():
       self.thread.quit()
       self.worker1.deleteLater()
       self.worker2 = Worker2()
       self.worker2.finished.connect(self.w2_finish)
       self.thread.started.connect(self.worker2.run)
       self.thread.start()
   
   def w2_finish():
       print("all done")


class Worker1(QObject):
   finished = pyqtSignal()
   def run():
      for i in range(5):
          print(f"This is worker1: {i}")
          sleep(1)
      self.finished.emit()

class Worker2(QObject):
   finished = pyqtSignal()
   def run():
      for i in range(5):
          print(f"This is worker2: {i}")
          sleep(1)
      self.finished.emit()

奇怪的是,有时这会按预期工作。我的意思是,我首先从worker 1 获取输出,然后从worker2 获取输出。然而,在某些情况下,worker 2 似乎是在worker 1 完成后执行的。有问题吗?我应该使用两个单独的线程实例来完成该任务吗?

python multithreading pyqt qthread worker
1个回答
0
投票

我依赖 QThreadPool() 编写了类似的代码:

import logging
import random
import sys
import time
from functools import partial

import qdarkstyle
from PyQt5.QtCore import QObject, pyqtSignal, QRunnable, QThreadPool
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QApplication

logger = logging.getLogger()
handler = logging.StreamHandler()
handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(threadName)s - %(message)s'))
logger.addHandler(handler)
logger.setLevel(logging.DEBUG)


class Signals(QObject):
    started = pyqtSignal(int)
    finished = pyqtSignal()


class WorkerTask(QRunnable):

def __init__(self, function: str):
    super().__init__()
    self.function = function
    self.signals = Signals()

def run(self):
    time_to_reach_pos = random.randint(2, 5)

    for i in range(time_to_reach_pos):
        logger.debug(f"{self.function}: {i + 1}/{time_to_reach_pos}")
        time.sleep(0.3)

    self.signals.finished.emit()


class MainWin(QWidget):
    def __init__(self):
        super().__init__()

        layout = QVBoxLayout()
        self.setLayout(layout)

        self.run_long_task()

    @staticmethod
    def run_long_task():
        threadpool = QThreadPool()

        grid_pos_task = WorkerTask(function="Go to grid position")
        autofocus_task = WorkerTask(function="Autofocus")

        # grid_pos_task.signals.finished.connect(threadpool.deleteLater)
        grid_pos_task.signals.finished.connect(partial(threadpool.start, autofocus_task))
        # grid_pos_task.finished.connect(lambda : print("ok"))

        threadpool.start(grid_pos_task)

        threadpool.waitForDone()
        print("All tasks finished")
© www.soinside.com 2019 - 2024. All rights reserved.