【问题标题】:PyQt5 ThreadingPyQt5 线程
【发布时间】:2018-08-09 14:37:35
【问题描述】:

尝试编写一个显示线程进程进度的类。我需要将此类用于所有“文件加载”操作;但是我在使其全球化时遇到了麻烦。

文件加载器.py:

from PyQt5.QtCore import pyqtSlot, pyqtSignal
from PyQt5.QtWidgets import QDialog
from PyQt5.uic import loadUi


class FileLoader(QDialog):
    completeSig = pyqtSignal()

    def __init__(self, parent=None):
        super(FileLoader, self).__init__(parent)
        self.filename = ""
        self.clientcode = ""
        self.thread = ""
        loadUi("GlobalUI/fileloader.ui", self)
        self.prgLoader.setValue(0)

    @pyqtSlot()
    def on_btnCancel_clicked(self):
        self.close()

    def closeEvent(self, e):
        self.thread.stop()

    def loadData(self):
        self.thread.totalSig.connect(self.prgLoader.setMaximum)
        self.thread.countSig.connect(self.prgLoader.setValue)
        self.thread.finished.connect(self.completed)
        self.thread.start()

    def completed(self):
        self.completeSig.emit()
        self.close()

loader.py

from PyQt5.QtCore import pyqtSignal, QThread

from fileloader import FileLoader


class DataLoader(QThread):
    totalSig = pyqtSignal(int)
    countSig = pyqtSignal(int)

    def __init__(self, parent=None):
        super(DataLoader, self).__init__(parent)
        self.threadactive = True
        self.commitsize = 300
        self.rowdata = []

    def run(self):
        print("Code Will Go Here For Loading the File")

    def stop(self):
        self.threadactive = False
        self.wait()


class PatDataLoader():
    def load(self, clientcode, filename):
        fl = FileLoader()
        fl.clientcode = clientcode
        fl.filename = filename
        fl.thread = DataLoader()
        fl.loadData()

我正在从另一个模块调用PatDataLoader.load("test","test.txt")。我遇到的问题是应用程序因QThread: Destroyed while thread is still running 而崩溃,因为我传递给文件加载器的线程进程似乎存在问题。我没有把这些部分正确地放在一起吗?

main.py:

from lmdb.patloader import PatDataLoader


    class PPSReportsApp(QMainWindow):
        def __init__(self, *args):
            super(PPSReportsApp, self).__init__(*args)
            loadUi("GlobalUI/ppsreportswindow.ui", self)
            #self.showMaximized()

    @pyqtSlot()
    def on_actionTest_triggered(self):
        pl = PatDataLoader()
        pl.load("TEST","testfile.txt")

【问题讨论】:

  • 你可以展示你如何调用PatDataLoader,也就是main。
  • 我从 QMainWindow 类的菜单触发器中调用它。查看编辑的代码
  • 错字:self.thread **a** ctive = Trueself.thread **A** ctive = False
  • 啊,是的。我纠正了错字;但是,问题仍然存在。它永远不会到达线程的 run 方法。
  • 是的,我知道,但是拼写错误会分散注意力,你应该避免不要用它们分散我们的注意力。

标签: python python-3.x pyqt pyqt5 qdialog


【解决方案1】:

在您的代码中,pl 是一个局部变量,因此当它完成执行 on_actionTest_triggered 时它将被删除,这可能会立即产生该问题。另一方面,no load 应该是静态方法,因为它不使用 self. self.thread 必须是None,比""

如何防止pl 在完成处理之前被删除?

flQDialog,因此您可以使用 exec_()

fileloader.py

class FileLoader(QDialog):
    completeSig = pyqtSignal()

    def __init__(self, parent=None):
        super(FileLoader, self).__init__(parent)
        self.filename = ""
        self.clientcode = ""
        self.thread = None
        loadUi("GlobalUI/fileloader.ui", self)
        self.prgLoader.setValue(0)

    @pyqtSlot()
    def on_btnCancel_clicked(self):
        self.close()

    def closeEvent(self, e):
        if self.thread:
            self.thread.stop()

    def loadData(self):
        if self.thread:
            self.thread.totalSig.connect(self.prgLoader.setMaximum)
            self.thread.countSig.connect(self.prgLoader.setValue)
            self.thread.finished.connect(self.completed)
            self.thread.start()

    def completed(self):
        self.completeSig.emit()
        self.close()

loader.py

class DataLoader(QThread):
    totalSig = pyqtSignal(int)
    countSig = pyqtSignal(int)

    def __init__(self, parent=None):
        super(DataLoader, self).__init__(parent)
        self.threadactive = True
        self.commitsize = 300
        self.rowdata = []

    def run(self):
        self.totalSig.emit(1000)
        print("Code Will Go Here For Loading the File")
        # emulate process
        for i in range(1000):
            if self.threadactive:
                QThread.msleep(10)
                self.countSig.emit(i)

    def stop(self):
        self.threadactive = False
        self.quit()
        self.wait()

class PatDataLoader():
    @staticmethod
    def load(clientcode, filename):
        fl = FileLoader()
        fl.clientcode = clientcode
        fl.filename = filename
        fl.thread = DataLoader()
        fl.loadData()
        fl.exec_() # <---

ma​​in.py

@pyqtSlot()
def on_actionTest_triggered(self):
    PatDataLoader.load("TEST","testfile.txt")

【讨论】:

  • 完美运行。感谢您的建议,我将详细了解 exec_() 方法。
猜你喜欢
  • 2017-12-08
  • 2021-07-29
  • 2017-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-30
  • 2021-06-06
  • 2018-06-10
相关资源
最近更新 更多