PyQt5执行耗时操作导致界面卡死的解决办法
场景:当用PyQt5开发一个工具 ,需要查询数据库时,一旦查询数据量大,界面就容易出现卡死、未响应等问题。
原因:推测原因: 在PyQt中,GUI界面本身就是一个主线程,当进行耗时查询时,查询操作直接跑在这个主线程上,GUI需要等待查询操作完成后才会响应,在等待这段时间,整个GUI就处于卡死的状态。在windows下,系统会认为这个程序运行出错了,会自动显示未响应,进而关闭程序。
解决办法:另开一个线程来执行这个查询操作(使用QThread)
例子如下(由于代码不方便展示,采用别人的例子):
# coding=utf-8
import sys
from PyQt5.QtWidgets import (QApplication, QWidget, QLabel, QHBoxLayout, QPushButton)
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import Qt, QThread, pyqtSignal
class MyGui(QWidget):
"""基础Gui页面"""
def __init__(self):
super().__init__()
self.init_ui() # 主窗口
def init_ui(self):
# self.setGeometry(300, 300, 600, 200) # 设置主窗口的位置和大小
self.setWindowTitle('Simple Little tools') # 设置主窗口的标题
self.setWindowIcon(QIcon('pics/icon1.gif')) # 设置主窗口的图标(左上角)
# 通用样式。页面上创建的一些部件,会默认使用设置的通用样式
self.setStyleSheet(
'QPushButton{font-weight: bold; background: skyblue; border-radius: 14px;'
' 300px; height: 28px; font-size: 20px; text-align: center;}'
'QPushButton:hover{background: rgb(50, 150, 255);}'
'QLabel{font-weight: bold; font-size: 20px; color: orange}'
)
self.main_layout() # 布局函数
self.show() # 显示窗口
def main_layout(self):
self.btn = QPushButton(' 点击计算1+2+...+50000000 ')
self.show_label = QLabel(' ')
self.show_label.setStyleSheet('color: black; background: skyblue; border-radius: 13px;')
hbox = QHBoxLayout()
hbox.addWidget(self.btn)
hbox.addWidget(self.show_label)
hbox.addStretch()
self.setLayout(hbox)
self.btn.clicked.connect(self.update) # 按钮点击后创建一个新的线程
def update(self):
self.btn.setText(' 计算中... ') # 主页面按钮点击后更新按钮文本
self.btn.setEnabled(False) # 将按钮设置为不可点击
self.cal = CalSumTheard() # 创建一个线程
self.cal._sum.connect(self.update_sum) # 线程发过来的信号挂接到槽函数update_sum
self.cal.start() # 线程启动
def update_sum(self, r):
self.show_label.setText(' ' + r + ' ') # 信号发过来时,更新QLabel内容
self.btn.setText(' 点击计算1+2+...+50000000 ') # 更新按钮
self.btn.setEnabled(True) # 让按钮恢复可点击状态
class CalSumTheard(QThread):
"""该线程用于计算耗时的累加操作"""
_sum = pyqtSignal(str) # 信号类型 str
def __init__(self):
super().__init__()
def run(self):
s, k = 0, 0
while k <= 50000000:
s += k
k += 1
self._sum.emit(str(s)) # 计算结果完成后,发送结果
if __name__ == '__main__':
app = QApplication(sys.argv)
qt = MyGui()
sys.exit(app.exec_())

浙公网安备 33010602011771号