PyQt6 基础操作:进度条 QProgressBar

1. 官方文档

PyQt6-ProgressBar

QProgressBar — PyQt Documentation v6.6.0

PyQt6-ProgressDialog

QProgressDialog — PyQt Documentation v6.6.0

Qt-ProgressBar

QProgressBar Class | Qt Widgets 6.6.1

Qt-QtCore.Qt

Qt Namespace | Qt Core 6.6.2

2. QProgressBar

进度条用于向用户显示操作进度,向用户表明程序仍在运行。 进度条使用步骤的概念,先对进度条指定最小和最大步骤数,程序在运行中向其提供当前步骤数,进度条显示已经完成的步骤的百分比。百分比的计算方法是将进度(value() - minimum())除以maximum() - minimum()。 可以用setMinimum()和setMaximum()指定最小和最大步骤数;用setValue()设置当前步骤数;用reset()让进度条重回开始。 如果minimum和maximum都设置为0,进度条显示一个忙碌的指示器,而不是百分比(在某些场景下,这个功能是很有用的)。

2.1 概述

枚举值

代码示例

描述

Direction

--

指定垂直进度条的文本方向(BottomToTop、TopToBottom)

方法

代码示例

描述

alignment() → AlignmentFlag

<horizontal_progressbar>

<vertical_progressbar>

获取当前对齐方式

setAlignment(AlignmentFlag)

<horizontal_progressbar>

<vertical_progressbar>

设置对齐方式

format() → str

<horizontal_progressbar>

获取文本显示格式

setFormat(Optional[str])

<horizontal_progressbar>

设置进度条文字显示格式,默认为%p%

已完成步骤占比 (%):%p

当前步骤 (进度条当前值):%v

总步骤数:%m

resetFormat()

<about_resetformat>

文本格式恢复为默认值:%p%

maximum() → int

<update_progress>

<__init__>

获取进度条最大值

setMaximum(int)

<run_all>

设置进度条最大值

minimum() → int

<__init__>

获取进度条最小值

setMinimum(int)

<run_all>

设置进度条最小值

setRange(int, int)

<_init_prepare>

<horizontal_progressbar>

<vertical_progressbar>

设置进度条最小值和最大值

setValue(int)

<_init_prepare>

<horizontal_progressbar>

<vertical_progressbar>

<update_progress>

设置进度条当前值

value() → int

<horizontal_progressbar>

<vertical_progressbar>

<update_progress>

获取当前值

text() → str

<horizontal_progressbar>

<vertical_progressbar>

获取当前文本

reset()

<about_reset>

进度条当前值复位

isTextVisible() → bool

<about_notext>

获取文本内容是否可见

setTextVisible(bool)

<about_notext>

设置文本内容是否可见

setTextDirection(Direction)

--

设置文本方向

orientation() → Orientation

<horizontal_progressbar>

<vertical_progressbar>

获取进度条方向

setOrientation(Orientation)

<horizontal_progressbar>

<vertical_progressbar>

设置进度条方向

信号

代码示例

描述

valueChanged(int)

--

在进度条的值发生改变时发送

2.2 代码

import sys
import threading
import time
from PyQt6.QtCore import pyqtSignal, QObject, Qt
from PyQt6.QtWidgets import QApplication, QMainWindow, QPushButton, QProgressBar, \
    QMessageBox, QLineEdit, QStyleFactory


class PercentageWorker(QObject):
    percentageChanged = pyqtSignal(int)

    def __init__(self, fake_flag=False, parent=None):
        super().__init__(parent)
        self._percentage = 0
        self.fake_flag = fake_flag

    @property
    def percentage(self):
        return self._percentage

    @percentage.setter
    def percentage(self, value):
        if self.fake_flag:
            return
        if self._percentage == value:
            return
        self._percentage = value
        self.percentageChanged.emit(self.percentage)


def user_defined_function(a=1, b=2, worker=None):
    """
    自定义函数
    """
    if worker is None:
        worker = PercentageWorker(fake_flag=True)

    # part1
    v1 = a * 10
    time.sleep(2)
    print('part1_end')
    worker.percentage = 1

    # part2
    v2 = b * 10
    time.sleep(2)
    print('part2_end')
    worker.percentage = 2

    # part3
    time.sleep(2)
    print('part3_end')
    worker.percentage = 3


class MyUi(QMainWindow):
    def __init__(self):
        super().__init__()
        self.resize(700, 700)

        self.button1 = QPushButton(self)
        self.button1.setText('点击运行程序')
        self.button1.move(20, 20)
        self.button1.resize(200, 40)

        self.progressbar = QProgressBar(self)
        self.progressbar.move(20, 100)
        self.progressbar.resize(400, 30)

        print(f'minimum: {self.progressbar.minimum()}, maximum: {self.progressbar.maximum()}')

        self.button1.clicked.connect(self.run_all)
        # self.progressbar.hide()

        self.pushbutton1 = QPushButton(self)
        self.pushbutton2 = QPushButton(self)
        self.pushbutton3 = QPushButton(self)
        self.pushbutton4 = QPushButton(self)
        self.pushbutton5 = QPushButton(self)
        self.pushbutton6 = QPushButton(self)
        self.lineedit1 = QLineEdit(self)
        self.lineedit2 = QLineEdit(self)
        self._init_prepare()

    def _init_prepare(self):
        self.lineedit1.move(120, 200)
        self.lineedit2.move(350, 200)
        self.lineedit1.resize(200, 30)
        self.lineedit2.resize(200, 30)

        self.pushbutton1.move(120, 250)
        self.pushbutton2.move(350, 250)
        self.pushbutton3.move(120, 300)
        self.pushbutton4.move(350, 300)
        self.pushbutton5.move(120, 350)
        self.pushbutton6.move(350, 350)

        self.pushbutton1.resize(200, 30)
        self.pushbutton2.resize(200, 30)
        self.pushbutton3.resize(200, 30)
        self.pushbutton4.resize(200, 30)
        self.pushbutton5.resize(200, 30)
        self.pushbutton6.resize(200, 30)

        self.lineedit1.setText(str(self.progressbar.alignment()))
        self.lineedit2.setText(str(self.progressbar.format()))
        self.pushbutton1.setText('设置为垂直进度条')
        self.pushbutton1.clicked.connect(self.vertical_progressbar)
        self.pushbutton2.setText('设置为水平进度条')
        self.pushbutton2.clicked.connect(self.horizontal_progressbar)
        self.pushbutton3.setText('水平进度条清空格式')
        self.pushbutton3.clicked.connect(self.about_resetformat)
        self.pushbutton4.setText('水平进度条不显示文本')
        self.pushbutton4.clicked.connect(self.about_notext)
        self.pushbutton5.setText('水平进度条清空值')
        self.pushbutton5.clicked.connect(self.about_reset)
        self.pushbutton6.setText('水平进度条 min=max=0')
        self.pushbutton6.clicked.connect(self.about_zero)

        self.progressbar.setRange(0, 100)
        self.progressbar.setValue(30)

    def vertical_progressbar(self):
        self.progressbar.show()
        self.progressbar.setOrientation(Qt.Orientation.Vertical)
        self.progressbar.resize(30, 400)
        self.progressbar.setStyle(QStyleFactory.create('windows'))
        self.progressbar.setAlignment(Qt.AlignmentFlag.AlignCenter)            # 无变化,windows样式下 垂直进度条不显示文本
        self.progressbar.setTextDirection(QProgressBar.Direction.TopToBottom)  # 无变化,windows样式下 垂直进度条不显示文本
        self.progressbar.setTextVisible(True)                                  # 无变化,windows样式下 垂直进度条不显示文本
        self.progressbar.setRange(0, 100)
        self.progressbar.setValue(50)
        self.lineedit1.setText(str(self.progressbar.text()))
        self.lineedit2.setText(str(self.progressbar.value()))
        print(f'text: {self.progressbar.text()}, value: {self.progressbar.value()}')

    def horizontal_progressbar(self):
        self.progressbar.show()
        self.progressbar.setOrientation(Qt.Orientation.Horizontal)
        self.progressbar.resize(400, 30)
        self.progressbar.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.progressbar.setTextVisible(True)
        self.progressbar.setFormat('运行进度: %p%')
        print(self.progressbar.format())
        # self.progressbar.setStyle(QStyleFactory.create('windowsvista'))
        self.progressbar.setStyle(QStyleFactory.create('Windows'))
        # self.progressbar.setStyle(QStyleFactory.create('Fusion'))
        self.progressbar.setRange(0, 100)
        self.progressbar.setValue(60)
        self.lineedit1.setText(str(self.progressbar.text()))
        self.lineedit2.setText(str(self.progressbar.value()))
        print(f'text: {self.progressbar.text()}, value: {self.progressbar.value()}')

    def about_resetformat(self):
        self.horizontal_progressbar()
        self.progressbar.resetFormat()

    def about_notext(self):
        print(self.progressbar.isTextVisible())
        self.horizontal_progressbar()
        self.progressbar.setTextVisible(False)
        print(self.progressbar.isTextVisible())

    def about_reset(self):
        self.horizontal_progressbar()
        self.progressbar.reset()

    def about_zero(self):
        self.horizontal_progressbar()
        self.progressbar.setRange(0, 0)

    def update_progress(self, value):
        self.progressbar.setValue(value)
        if self.progressbar.value() == self.progressbar.maximum():
            self.progressbar.hide()
            QMessageBox.information(self, '通知', '程序运行结束')

    def run_all(self):
        self.progressbar.setMinimum(0)
        self.progressbar.setMaximum(3)
        self.progressbar.show()
        worker = PercentageWorker(fake_flag=False)
        worker.percentageChanged.connect(self.update_progress)
        threading.Thread(
            target=user_defined_function,
            args=(2,),
            kwargs=dict(b=4, worker=worker),
            daemon=True,
        ).start()


if __name__ == "__main__":
    app = QApplication(sys.argv)
    print(QStyleFactory.keys())
    app.setStyle(QStyleFactory.create('Fusion'))
    w = MyUi()
    w.show()
    sys.exit(app.exec())

3. 细节说明

1. AlignmentFlag

关于AlignmentFlag,不同设置方式对应的效果,可以通过Dt Designer便捷的查看。

主要有两种效果:

文本靠右(默认)

文本居中(progressbar.setAlignment(Qt.AlignmentFlag.AlignCenter))

AlignmentFlag具体内容可参考Qt文档。

2. format

参考Qt文档。

3. Vertical ProgressBar

1)windows样式下,垂直模式的进度条不显示文本;如需显示文本,建议与QLabel组合使用。

可以使用QStyleFactory.keys()方法返回当前系统支持的QStyle名称列表。

from PyQt6.QtWidgets import QStyleFactory

print(QStyleFactory.keys())

返回值如下:

['windowsvista', 'Windows', 'Fusion']

(默认值为:‘windowsvista‘)

2)可以对QProgressBar设置上述三种不同样式,对比一下效果。

self.progressbar.setStyle(QStyleFactory.create('windowsvista'))
# self.progressbar.setStyle(QStyleFactory.create('Windows'))
# self.progressbar.setStyle(QStyleFactory.create('Fusion'))
windowsvista (默认)
Windows
Fusion

3)也可以通过app.setStyle,更改所有控件的风格。

if __name__ == "__main__":
    app = QApplication(sys.argv)
    app.setStyle(QStyleFactory.create('Fusion'))
    w = MyUi()
    w.show()
    sys.exit(app.exec())

4. 针对某外部函数,在ui界面显示函数运行进度

参考代码部分<PercentageWorker>、<user_defined_function>、<update_progress>、<run_all>

4. 效果展示

1. 水平进度条

对齐方式居中(水平居中&垂直居中)+自定义文本格式+设置进度条风格为windows

2. 垂直进度条

3. 显示外部函数运行进度

函数运行结束后出现弹窗提示运行结束。

5. 参考链接

python - How to update PyQt progressbar from an independent function with arguments? - Stack Overflow

  • 33
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值