簡體   English   中英

PyQT5 多線程問題

[英]PyQT5 Multi Thread Issue

我正在嘗試使用 PYQT5 和 Qthread 運行多線程

我有兩個與線程關聯的按鈕(進度條和一個操作等待 1 秒,然后打印“完成”),它們在同一個 Class 中聲明時工作正常。

我確實有第三個按鈕,我鏈接到另一個 Class 中插入的操作。 這使我的程序在沒有任何日志消息的情況下崩潰。 使程序崩潰的確切原因是“self.thread2.start()”行。

我不明白為什么這不起作用? 你能幫我理解這個問題嗎?

提前致謝

import sys
from PyQt5.QtCore  import *
from thread_progressbar import *
from Test_MT import *


class SimulationUi(QtWidgets.QDialog):
    def __init__(self):
        super(SimulationUi, self).__init__()
        self.btnStart = QtWidgets.QPushButton('Start')
        self.btnStart2 = QtWidgets.QPushButton('Start')
        self.btnStop = QtWidgets.QPushButton('Stop')
        self.btnStop2 = QtWidgets.QPushButton('Stop')
        self.btnQuit = QtWidgets.QPushButton('Quit')

        self.myprogressbar = QtWidgets.QProgressBar()
        self.myprogressbar2 = QtWidgets.QProgressBar()

        self.grid = QtWidgets.QGridLayout()
        self.grid.setSpacing(10)
        self.grid.addWidget(self.btnStart,1,0)
        self.grid.addWidget(self.btnStop,1,1)
        self.grid.addWidget(self.myprogressbar,2,0,1,3)
        self.grid.addWidget(self.btnStart2, 3, 0)
        self.grid.addWidget(self.btnStop2, 3, 1)
        self.setLayout(self.grid)

        # ------------------------
        #MULTI-THREAD MANAGEMENT
        #------------------------
        self.thread = QThread()
        self.thread.start()
        self.worker = thread_progressbar()
        self.worker.moveToThread(self.thread)
        self.worker.setValue.connect(self.myprogressbar.setValue)
        self.btnStart.clicked.connect(self.worker.startpgbar)
        self.btnStop.clicked.connect(lambda: self.worker.stoppgbar())

        class_tst = MakeList()
        class_tst.define_thread(self.btnStart2)

        self.thread3 = QThread()
        self.thread3.start()
        self.worker3 = Test()
        self.worker3.moveToThread( self.thread3 )
        self.btnStop2.clicked.connect( self.worker3.MT )


    def stop_thread(self):
        self.worker.stop()
        self.thread.quit()
        self.thread.wait()

    def quit_application(self):
        self.close()


class MakeList():
    def __init__(self):
        super(MakeList, self).__init__()
    def define_thread(self, MyObject):
        self.thread2 = QThread()
        self.thread2.start()
        self.worker2 = Test()
        self.worker2.moveToThread(self.thread2 )
        MyObject.clicked.connect( self.worker2.MT )


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    simul = SimulationUi()
    simul.show()
    sys.exit(app.exec_())

  • Test_MT 文件
import os, time
from PyQt5 import QtCore


class Test(QtCore.QObject):
    def MT(self):
        time.sleep(1)
        print("done")

由於SimulationUi.__init__中對MakeList實例的唯一引用是局部變量class_tst ,因此該 object 及其屬性將在SimulationUi.__init__返回時被垃圾收集。 由於它的一個屬性是一個正在運行的線程( class_tst.thread2 ),這會導致程序崩潰。 解決此問題的最簡單方法是通過將 MakeList object 分配給SimulationUi的實例變量而不是局部變量(即在SimulationUi.__init__中使用self.class_tst = MakeList()而不是class_tst=MakeList()來持久引用MakeList object) .

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM