python - 如何通过响应式进度条重复使用 Qthread

标签 python pyqt pyqt5 qthread qprogressbar

当使用 python pyqt 时,我制作了一个 Qprogressbar,并使用 Q 线程更新数字。下面显示的代码第一次运行成功,但是再次运行就会崩溃。

这是针对Python PyQt5,在Python 3.5系统中。我尝试将进度条重置为 0,但似乎不正确

这是我点击加载文件按钮后的调用函数,加载文件按钮和进度条位于QtWidgets.Qmainwindows中

loading_event_name = QtWidgets.QFileDialog.getOpenFileNames(self, 'CSV File', 'C:\\', '*.csv')
self.loading_progress_bar.reset()
self.loading_thread = QThread()
self.loading_worker = Load_Task_Thread()

self.loading_worker.moveToThread(self.loading_thread)
self.loading_thread.started.connect(self.loading_worker.run)
self.loading_thread.start()
self.loading_worker.Load_taskFinished.connect(self.Load_onFinished)
self.loading_worker.Loading_progressChanged.connect(self.loading_progress_bar.setValue, Qt.QueuedConnection)'''

第一个加载文件线程将完美工作,但是如果我想加载新文件,下次单击时,软件将崩溃,线程不会更新,进度条不会像第一次那样更新数字,并且自从我重置以来一直保持为零它。在 Debug模式下,我也无法向进度条发出任何数字:

class Load_Task_Thread(QThread):
  Load_taskFinished = pyqtSignal()
  Loading_progressChanged = pyqtSignal(int)
  def run(self):
    progress = 0
    for file_name_num in range(len(loading_event[0])):
       progress = 90 * file_name_num/len(loading_event_name[0])
       self.Loading_progressChanged.emit(progress)
       1+1.....
    self.Loading_progressChanged.emit(100)
    self.Load_taskFinished.emit()

我期望无论点击多少次选择新文件,进度条都能更新。或者有没有其他简单的方法可以显示进度条来显示加载过程。

最佳答案

您可能还有其他错误,但从您提供的代码中我观察到以下错误:

  • 您已经创建了一个 QThread (Load_Task_Thread),并将其移动到另一个 QThread,这是不必要的,因为 Load_Task_Thread 是一个 QObject 就足够了。

  • 不必每次启动进程时都创建一个 QThread,因为存在于线程中的 QObject 就足够了。

考虑到上述情况,我实现了以下示例:

from functools import partial

from PyQt5 import QtCore, QtGui, QtWidgets


class Load_Task_Worker(QtCore.QObject):
    started = QtCore.pyqtSignal()
    finished = QtCore.pyqtSignal()
    progressChanged = QtCore.pyqtSignal(int)

    @QtCore.pyqtSlot(list)
    def run(self, filenames):
        total = len(filenames)
        self.started.emit()
        self.progressChanged.emit(0)
        for i, filename in enumerate(filenames, 1):
            # start process
            # ...
            # end process
            progress = 100 * i // total
            self.progressChanged.emit(progress)
        self.finished.emit()


class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.button = QtWidgets.QPushButton("Start Task")
        self.loading_progress_bar = QtWidgets.QProgressBar()

        lay = QtWidgets.QVBoxLayout(self)
        lay.addWidget(self.button)
        lay.addWidget(self.loading_progress_bar)

        thread = QtCore.QThread(self)
        thread.start()

        self.worker = Load_Task_Worker()
        self.worker.moveToThread(thread)

        self.button.clicked.connect(self.onClicked)
        self.worker.progressChanged.connect(self.loading_progress_bar.setValue)
        self.worker.finished.connect(self.onFinished)

    @QtCore.pyqtSlot()
    def onFinished(self):
        self.button.setEnabled(True)

    @QtCore.pyqtSlot()
    def onClicked(self):
        filenames, _ = QtWidgets.QFileDialog.getOpenFileNames(
            self, "CSV File", "C:\\", "*.csv"
        )
        if filenames:
            self.button.setEnabled(False)
            self.loading_progress_bar.reset()
            wrapper = partial(self.worker.run, filenames)
            QtCore.QTimer.singleShot(0, wrapper)
        else:
            print("not selected files")


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())

关于python - 如何通过响应式进度条重复使用 Qthread,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58475606/

相关文章:

python - PyQt 将 QWidget 的方向从右向左更改

Python:isinstance(i, type(i)) 可以评估为 False 吗?

python - 从列表条目访问 SQL 数据

python - Qmessagebox 不工作

python - QStyledItemDelegate 在QTableView中显示QComboBox

python - 如何在 QML 中将 @pyqtSlot 装饰器与其他装饰器一起使用?

python - 通过 GAE header 问题发布请求

python - CPython 中的 dprintf

python - 如何测试 django 消息中是否存在某个级别

python - 具有两种不同颜色的行背景的 QListView