import sys
from PySide6.QtWidgets import QPushButton,QLabel,QProgressDialog,QHBoxLayout,QVBoxLayout,QWidget,QApplication,QMainWindow
from PySide6.QtCore import *
class QProgressDialogDemo(QMainWindow):
def __init__(self):
super(QProgressDialogDemo, self).__init__()
#设置窗口大小
self.resize(400, 150)
self.setWindowTitle("QProgressDialogDemo")
btn = QPushButton("开始")
btn.clicked.connect(self.btnClick)
#创建水平布局
layout = QHBoxLayout()
layout.addWidget(btn)
mainFrame = QWidget()
mainFrame.setLayout(layout)
self.setCentralWidget(mainFrame)
def btnClick(self):
elapsed = 200000
#self.progressDialog = QProgressDialog('下载进度','取消',0,elapsed,self)
self.progressDialog = QProgressDialog()
self.progressDialog.setLabelText("wait ...")
self.progressDialog.setRange(0,elapsed)
self.progressDialog.setCancelButton(None)
self.progressDialog.setWindowTitle('QProgressDialog')
self.progressDialog.setStyleSheet(u"QProgressBar::chunk\n"
"{\n"
"border-radius:11px;\n"
"background:qlineargradient(spread:pad,x1:0,y1:0,x2:1,y2:0,stop:0 #01FAFF,stop:1 #26B4FF);\n"
"}\n"
"QProgressBar#progressBar\n"
"{\n"
"height:22px;\n"
"text-align:center;/*\u6587\u672c\u4f4d\u7f6e*/\n"
"font-size:14px;\n"
"color:white;\n"
"border-radius:11px;\n"
"background: #1D5573 ;\n"
"}")
self.progressDialog.show()
for val in range(elapsed):
self.progressDialog.setValue(val)
QCoreApplication.processEvents()
if self.progressDialog.wasCanceled():
break
self.progressDialog.setValue(elapsed)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = QProgressDialogDemo()
main.show()
sys.exit(app.exec_())
取消进度条中的calcel按钮
self.progressDialog.setCancelButton(None)
设置进度条的整体样式
self.progressDialog.setStyleSheet(u"QProgressBar::chunk\n"
"{\n"
"border-radius:11px;\n"
"background:qlineargradient(spread:pad,x1:0,y1:0,x2:1,y2:0,stop:0 #01FAFF,stop:1 #26B4FF);\n"
"}\n"
"QProgressBar#progressBar\n"
"{\n"
"height:22px;\n"
"text-align:center;/*\u6587\u672c\u4f4d\u7f6e*/\n"
"font-size:14px;\n"
"color:white;\n"
"border-radius:11px;\n"
"background: #1D5573 ;\n"
"}")
将进度条搭载在线程上
# -*- coding: utf-8 -*-
# 正确做法(使用信号与槽)
# 先定义一个全局信号 a = Signal(str)
# 然后将信号a与工作实例的方法(do_some_work())绑定
# 新建一个函数,给a发信号即可开始执行(do_some_work())任务
import sys
from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QLabel, QPushButton, QVBoxLayout, QProgressBar
from PySide6.QtCore import QThread, QObject, Signal
import time
# 工作类,并继承QObject
class Worker(QObject):
progress = Signal(int)
completed = Signal(int)
# 需要执行的耗时任务
def do_work(self, n):
print("-do work----\n")
for i in range(1, n + 1):
time.sleep(1)
self.progress.emit(i)
self.completed.emit(i)
class MainWindow(QMainWindow):
a = Signal(int) # 全局信号
def __init__(self):
super(MainWindow, self).__init__()
# ui部分
self.setGeometry(100, 100, 300, 50)
self.setWindowTitle('QThread Demo')
self.widget = QWidget()
layout = QVBoxLayout()
self.widget.setLayout(layout)
self.setCentralWidget(self.widget)
self.progress_bar = QProgressBar(self)
self.progress_bar.setValue(0)
self.btn_start = QPushButton('Start', clicked=self.start)
layout.addWidget(self.progress_bar)
layout.addWidget(self.btn_start)
# 创建一个线程和一个工作实例
self.worker = Worker()
self.worker_thread = QThread()
###########注意#########################################################################################
# 官方还有一个deleteLater()方法,该方法来自工作实例(即self.worker),因为继承了QObject
# 有什么作用?大白话就是把刚放进线程里的工作实例释放掉(拿出来、删掉),这样,线程里就什么都没有了
# 例子:self.worker_thread.finished.connect(self.worker.deleteLater)
# 线程里没有工作实例了,自然就无法再次调用了,看如下报错
# Traceback (most recent call last):
# File "D:\Py Workspace\baseqt\test.py", line 49, in <lambda>
# self.worker_thread.finished.connect(lambda: print(self.worker))
# RuntimeError: Internal C++ object (Worker) already deleted.
# 报错已经说的很明白了,object (Worker) already deleted
# 什么时候用?多数是不用的,看情况而定吧!
# 那他是为了什么?一种优化,释放掉不用的对象,释放内存呗,注意了,你的对象还要用就不要去释放了
#######################################################################################################
# self.worker_thread.finished.connect(self.worker.deleteLater)
# self.worker_thread.finished.connect(lambda: print(self.worker)) # 测试释放掉对象后的报错
# 线程里的progress信号与进度条更新函数绑定
self.worker.progress.connect(self.update_progress)
# 线程里的completes信号与完成函数绑定
self.worker.completed.connect(self.complete)
# 全局信号绑定工作实例的方法
self.a.connect(self.worker.do_work)
# 把工作实例放进线程里
self.worker.moveToThread(self.worker_thread)
# 开始线程
self.worker_thread.start()
def start(self):
print("------------start--------")
self.btn_start.setEnabled(False)
n = 5
self.progress_bar.setMaximum(n)
self.a.emit(n) # 给全局信号发信号,触发线程内工作实例的方法执行
def update_progress(self, v):
print("---update _ progress--\n")
self.progress_bar.setValue(v) # 与线程内的progress信号绑定,更新进度条
def complete(self, v): # 与线程内completed信号绑定,线程工作一结束就会触发此函数
print("---complete-------\n")
self.progress_bar.setValue(0)
self.btn_start.setEnabled(True)
# 线程内的耗时任务执行完了,但创建的这个线程不一定也会结束,所以还需下面几句来主动退出
print(self.worker_thread.isRunning()) # 打印True表示线程还在
self.worker_thread.quit() # 结束线程
self.worker_thread.wait() # 等待线程结束
print(self.worker_thread.isRunning()) # 打印False表示线程已退出
# 注意:没有quit()和wait(),在x掉窗口时控制台会报“QThread: Destroyed while thread is still running”
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())
进度条在QProgressDialog在类的初始化后就会立即弹出问题处理。
对QProgressDialog初始化的类进行reset设置
self.progressDialog = QProgressDialog(Form)
self.Progressbar(Form)
self.retranslateUi(Form)
QMetaObject.connectSlotsByName(Form)
#change this code for start process bar
def Progressbar(self,Form):
elapsed = 1000000
self.progressDialog.reset()
self.progressDialog.setLabelText("wait ...")
self.progressDialog.setRange(0,elapsed)
self.progressDialog.setCancelButton(None)
self.progressDialog.setWindowTitle('start read config')
self.progressDialog.setStyleSheet(u"QProgressBar::chunk\n"
"{\n"
"border-radius:11px;\n"
"background:qlineargradient(spread:pad,x1:0,y1:0,x2:1,y2:0,stop:0 #01FAFF,stop:1 #26B4FF);\n"
"}\n"
"QProgressBar#progressBar\n"
"{\n"
"height:22px;\n"
"text-align:center;/*\u6587\u672c\u4f4d\u7f6e*/\n"
"font-size:14px;\n"
"color:white;\n"
"border-radius:11px;\n"
"background: #1D5573 ;\n"
"}")
感觉弹出框的title太丑了,准备将title去掉
使用方法:setWindowFlags
self.progressDialog.setWindowFlags(Qt.Tool|Qt.FramelessWindowHint)
使用函数 为: QWidget.setWindowFlags()
置顶 参数为: Qt.WindowStaysOnTopHint
无边框 参数为: Qt.FramelessWindowHint
无任务栏图标 参数为: Qt.Tool
使用后的效果图: