首页 > 解决方案 > 达到/设置某个值后如何重置 PYQT5 进度条?

问题描述

我目前正在创建将一些数据分析脚本联系在一起的基本 GUI。这些脚本可能需要(取决于输入的数据)几分钟才能运行,我希望将进度条合并到 GUI 中以确认脚本正在运行。

然而,作为一个自学的python(er),我在为我的问题实施解决方案时遇到了一些困难。我可以在运行 Open_Instructions 方法时更新进度条,但是当我运行 Open_generic 方法时,进度条会在 20%、40% 和 60% 之间不断循环,并且不会完成。下面是我的脚本。注意 - 我已经删除了非必要的(?)行

import os
from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def Open_Instructions(self):
        self.timer = QtCore.QTimer(self.centralwidget)
        self.timer.timeout.connect(self.Increase_Instructions)
        self.timer.start(1000)
        url = 'https://github.com/Example'
        path = os.path.join(main_path,
                        'Manual',
                        'Example.pdf')
        open_resource(path, url)

    def Increase_Instructions(self):
        self.progressBar.setValue(self.progressBar.value()+20)

    def reset(self):
        self.progressBar.setValue(0)

    def Open_Generic(self):
        self.timer = QtCore.QTimer(self.centralwidget)
        self.timer.timeout.connect(self.reset)
        self.timer.timeout.connect(self.Increase_Instructions)
        self.timer.start(2000)
        path = os.path.join(main_path,
                        'Resources',
                        'Generic_Example.pdf')
        open_resource(path)

    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(521, 704)
        MainWindow.setStyleSheet("background-color: rgb(235, 235, 235);")
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")

        self.progressBar = QtWidgets.QProgressBar(MainWindow)
        self.progressBar.setGeometry(128, 670, 300, 25)
        self.progressBar.setProperty("value", 0)
        self.progressBar.setMaximum(100)
        self.progressBar.setValue(0)
    
        self.Instruction_Button = QtWidgets.QPushButton(self.centralwidget)
        self.Instruction_Button.setGeometry(QtCore.QRect(55, 210, 141, 31))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(12)
        font.setBold(True)
        self.Instruction_Button.setFont(font)
        self.Instruction_Button.clicked.connect(self.Open_Instructions)
        self.Instruction_Button.setObjectName("Instruction_Button")
        self.Instruction_Button.raise_()
    
        self.Generic_Datasheet_Button = QtWidgets.QPushButton(self.centralwidget)
        self.Generic_Datasheet_Button.setGeometry(QtCore.QRect(310, 450, 161, 31))
        font = QtGui.QFont()
        font.setFamily("Arial")
        font.setPointSize(12)
        font.setBold(True)
        font.setWeight(75)
        self.Generic_Datasheet_Button.setFont(font)
        self.Generic_Datasheet_Button.setText("Generic datasheet")
        self.Generic_Datasheet_Button.setObjectName("Generic_Datasheet_Button")
        self.Generic_Datasheet_Button.clicked.connect(self.Open_Generic)

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

标签: pythonuser-interfacepyqt5progress-bar

解决方案


如果要重置进度条值,需要检查是否达到最大值;如果您还想延迟重置,则需要另一个不同的计时器来执行此操作,小心在新进程启动后立即停止它:如果重置计时器的间隔大于增加值的间隔,则可能会在进度条已显示大于 0 的值时重置它。

请注意,您应该重用现有的计时器,而不是每次都创建一个新计时器,否则您最终会得到多个并发计时器。

from PyQt5 import QtCore, QtWidgets

class Test(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        layout = QtWidgets.QVBoxLayout(self)
        self.resetRadio = QtWidgets.QRadioButton('Reset after end')
        layout.addWidget(self.resetRadio)
        self.resetRadio.setChecked(True)
        self.keepRadio = QtWidgets.QRadioButton('Keep value after end')
        layout.addWidget(self.keepRadio)
        self.startButton = QtWidgets.QPushButton('Start')
        layout.addWidget(self.startButton)
        self.startButton.clicked.connect(self.startTimer)

        self.progressBar = QtWidgets.QProgressBar()
        layout.addWidget(self.progressBar)

        self.timer = QtCore.QTimer(interval=1000, timeout=self.timeout)
        self.resetTimer = QtCore.QTimer(interval=2000, timeout=self.progressBar.reset, singleShot=True)

    def startTimer(self):
        # stop the reset timer if it's running
        self.resetTimer.stop()
        self.progressBar.setValue(0)
        self.timer.start()

    def timeout(self):
        if self.progressBar.value() == self.progressBar.maximum():
            # the maximum has been reached, stop the timer
            self.timer.stop()
            if self.resetRadio.isChecked():
                # we are going to reset the progress bar, let's start the timer
                # that will do that
                self.resetTimer.start()
        else:
            # increase the value
            self.progressBar.setValue(self.progressBar.value() + 20)


if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = Test()
    w.show()
    sys.exit(app.exec_())

推荐阅读