【问题标题】:How to reset a PYQT5 progress bar once a certain value has been reached/set?达到/设置某个值后如何重置 PYQT5 进度条?
【发布时间】:2020-07-20 14:14:35
【问题描述】:

我目前正在创建将一些数据分析脚本联系在一起的基本 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_())

【问题讨论】:

  • 删除self.timer.timeout.connect(self.reset) 函数中的self.timer.timeout.connect(self.reset) 行,因为它会导致总是重置进度条。也不要修改pyuic生成的文件,它们应该保持原样;阅读更多关于using Designer的信息。
  • 嗨,正如建议的那样,删除该行确实会阻止进度条不断重置,但我现在留下了一个进度条,它只能使用一次,因为它保持在 100%,因此为什么我首先尝试使用重置方法。关于生成的pyuic文件,是不是我修改了pyuic文件导致进度条出现问题?
  • 不,这个问题与您使用的是 pyuic 文件这一事实无关,但它会使代码不必要地混乱(这可能会增加出现错误的可能性)。除此之外,您应该更清楚如何/何时重置进度条:它是否应该在达到最大值时重置尽快(意味着永远不会“看到”100)?它是否应该在下一个周期重新启动,它达到最大值之后?之后计时器应该停止还是继续?
  • 我明白了,谢谢,我将再次阅读 Deisgner 文档。关于进度条,我希望进度条达到最大值(100%)并保持任意时间(比如 5 秒),或者保持最大值直到使用另一种方法并且进度将重置回到 0% 并在第二种方法运行时再次开始。

标签: python user-interface pyqt5 progress-bar


【解决方案1】:

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

【讨论】:

  • @Trincatalyst 如果我的回答解决了您的问题,请记住通过单击左侧的复选标记将其设置为已接受。
猜你喜欢
  • 1970-01-01
  • 2021-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-23
  • 1970-01-01
相关资源
最近更新 更多