为什么这个pyqt5 qthread只在每两次按钮点击运行一次?

时间:2018-03-28 03:35:28

标签: python qt5 pyqt5 qthread

我有一个我想要的程序,点击按钮,创建一个qthread并运行一些代码。最后,我希望主线程破坏工作线程。

以下代码显示了我的一次尝试。据我所知,它只在第一次按钮点击时创建线程,在第二次点击时它会销毁前一个线程并创建并运行work()函数。如果您在按钮单击之间等待很长时间,则会看到第一个按钮单击的外观,它不会运行work()函数。 任何人都可以看到我做错的事情。我有一个更复杂的例子形成别人,我试图分解成一个较小的部分。(Pyqt5 qthread + signal not working + gui freeze

代码:

import time
import sys

from PyQt5.QtCore import QObject, QThread, pyqtSignal, pyqtSlot
from PyQt5.QtWidgets import QApplication, QPushButton, QTextEdit, QVBoxLayout, QWidget


class Worker(QObject):
    """
    Must derive from QObject in order to emit signals, connect slots to other signals, and operate in a QThread.
    """
    sigDone = pyqtSignal(int)

    def __init__(self, id: int):
        print("Here 11")
        super().__init__()
        print("Here 9")
        self.__id = id

    @pyqtSlot()
    def work(self):
      print("Here 10")
      for count in range(20):
          print("ID: " + str(self.__id) + ", Count: " + str(count))
          time.sleep(0.1)
          app.processEvents()  # this could cause change to self.__abort
      self.sigDone.emit(self.__id)
      #Need a done signal.          

class MyWidget(QWidget):
    def __init__(self):
        super().__init__()
        print("Here 1")
        self.setWindowTitle("Thread Example")
        form_layout = QVBoxLayout()
        self.setLayout(form_layout)
        self.resize(400, 400)
        print("Here 2")
        self.btnStartWorker = QPushButton()
        self.btnStartWorker.clicked.connect(self.start_worker)
        self.btnStartWorker.setText("Start Worker")
        form_layout.addWidget(self.btnStartWorker)

        self.__threads = None

    def start_worker(self):
        print("Here 3")
        worker = Worker(999)
        thread = QThread()
        print("Here 4")
        self.__threads = []
        self.__threads.append(thread)
        print("Here 5")
        worker.moveToThread(thread)
        worker.sigDone.connect(self.workerDone)
        print("Here 6")
        thread.started.connect(worker.work)
        print("Here 7")
        thread.start()
        print("Here 8")    

    @pyqtSlot(int)
    def workerDone(self, threadNumber):
        print("Here 12")
        print("Thread " + str(threadNumber) + " is done.")
        for thread in self.__threads:
            thread.quit()
            thread.wait()
        print("Here 13")

if __name__ == "__main__":
    app = QApplication([])

    form = MyWidget()
    form.show()

    sys.exit(app.exec_())

某些按钮点击的结果:

E:\myCode\python\pyQt>python3 pyQtv6.py
Here 1
Here 2
Here 3
Here 11
Here 9
Here 4
Here 5
Here 6
Here 7
Here 8
Here 3
Here 11
Here 9
Here 4
QThread: Destroyed while thread is still running
Here 5
Here 6
Here 7
Here 8
Here 10
ID: 999, Count: 0
ID: 999, Count: 1
ID: 999, Count: 2
ID: 999, Count: 3
ID: 999, Count: 4
ID: 999, Count: 5
ID: 999, Count: 6
ID: 999, Count: 7
ID: 999, Count: 8
ID: 999, Count: 9
ID: 999, Count: 10
ID: 999, Count: 11
ID: 999, Count: 12
ID: 999, Count: 13
ID: 999, Count: 14
ID: 999, Count: 15
ID: 999, Count: 16
ID: 999, Count: 17
ID: 999, Count: 18
ID: 999, Count: 19
Here 12
Thread 999 is done.
Here 13
Here 3
Here 11
Here 9
Here 4
Here 5
Here 6
Here 7
Here 8
Here 3
Here 11
Here 9
Here 4
QThread: Destroyed while thread is still running
Here 5
Here 6
Here 7
Here 8

0 个答案:

没有答案