1. 官方文档
PyQt6-ProgressBar | |
PyQt6-ProgressDialog | |
Qt-ProgressBar | |
Qt-QtCore.Qt |
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. 显示外部函数运行进度
函数运行结束后出现弹窗提示运行结束。