网站优化

网站优化

Products

当前位置:首页 > 网站优化 >

如何让PyQt5界面不再出现无响应问题?

GG网络技术分享 2026-04-17 08:47 2


哎,说起PyQt5,那真是又爱又恨。功能强大是真,但一不小心就给你来个“石化”界面点啥都动不了!特别是那些复杂的程序,稍微有点耗时的操作,UI直接卡住用户体验简直糟糕透顶!我之前搞了个数据分析的小工具,后来啊一运行,界面就跟被施了魔法一样,愣是半天没反应。当时真是抓狂啊,他急了。!

为什么PyQt5界面会无响应?

这事儿吧,说白了就是主要原因是Qt的事件循环机制。简单Qt有一个主线程负责处理所有的用户交互和界面更新。如果你在主线程里施行了什么特别耗时的任务, 那么这个主线程就会被堵塞住无法及时处理用户的输入和界面的刷新。后来啊就是……你看着屏幕发呆,啥也干不了,火候不够。。

PyQt5 解决界面无响应方案

就好像你一边要洗衣服、做饭、看电视一样。如果洗衣服这个活儿特别费时间, 一句话概括... 你就没精力管其他事儿了。等你洗完衣服回头一看,饭都糊了!

举个栗子

看看这段代码吧!这是我当初犯错的时候写的:

import sys
import time
from PyQt5 import QApplication, QWidget, QProgressBar, QPushButton, QHBoxLayout
class MyWidget:
    def __init__:
        super.__init__
        self.progress = 0
        self.progressBar = QProgressBar
        self.progressBar.setGeometry
        self.button = QPushButton
        self.button.clicked.connect
        layout = QHBoxLayout
        layout.addWidget
        layout.addWidget
        self.setLayout
    def _clicked:
        while True:  # 这段循环可恶啊!
            time.sleep  # 模拟耗时操作
            self.progress =  % 101
            self.progressBar.setValue
if __name__ == '__main__':
    app = QApplication
    w = MyWidget
    w.show
    sys.exit)

很棒。 这段代码的功能很简单:点击按钮后进度条就会开始滚动。但是……当你点击按钮的时候会发现什么?没错!界面直接卡死了!进度条根本不滚动!气不气?

解决PyQt5界面无响应的方案

我比较认同... 别担心,解决这个问题的方法其实很简单。核心思想就是:**把耗时的任务从主线程里移出去!** 主要有两种方法:

1、使用QThread

QThread是Qt提供的多线程类。你可以创建一个继承自QThread的类,把耗时的任务放在run方法里施行。然后启动这个线程就可以了。

QThread使用示例

python import sys import time from PyQt5 import QThread, pyqtSignal, QApplication, QWidget, QProgressBar, QPushButton, QHBoxLayout,妥妥的!

哈基米! class MyWorker: #继承QThread类实现多线程功能哦~ 非常重要!!!不然没法跑起来滴~哈~哈~哈~哈~~!@#!@~!@~!@~!@!~!@!~!@!~!!@!~!@!!~!@!~!@!~!!! #加这么多感叹号是为了强调重要性!!!!!!!!! 加油!!!!!!!!!努力!!!!!!加油!!!!!!!!! 加油!!!!!!!!! 加油!!!!!!!!! 加油!!!!!!!!! 加油!!!!!!!!! 加油!!!!!!!!! 加油!!!!!!!!!!加油!!!!!!!!!!加油!!!!!!!!!!加油!!!!!!!!!!加油!!!!!!!!!!加油!!!!!!!!!!加油!!!!!!!!!!加油!!!!!!!!!!! #嘿嘿嘿嘿嘿嘿嘿嘿嘿 感觉像个傻子一样写注释 ~哈哈哈哈哈哈哈哈哈~~~!!! #不要介意!!! 真的!!! #太开心啦~~~~~~~~~~!!!!!!! #快乐的事情太多啦~~~~~~~~~~!!!!!!! #我喜欢Python~~~~~~~~~~!!!!!!! #我要成为一个优秀的程序员~~~~~~~~~~!!!!!!! #加油!!!!!!!!!!!!!!!!!!!!! #别笑我啦~~~~~~~~~~~~~~~!!!!!!!!!!!!!!!!!!!!!! #真的啦~~~~~~~~~~~~~~~!!!!!!!!!!!!!!!!!!!!!! #相信自己~~~~~~~~~~~~~~~!!!!!!!!!!!!!!!!!!!!!! #你也可以的~~~~~~~~~~~~~~~!!!!!!!!!!!!!!!!!!!!!! #努力努力再努力~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!!! #今天也要开心呀~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!!! #虽然有点啰嗦~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #但是很重要哦 ~ ~ ~ ~ ~ !!! #重要的事情说三遍 #重要的事情说三遍 #重要的事情说三遍 #重要的事情说三遍

timeout = pyqtSignal  # 定义一个信号用来通知主线程完成任务啦!!!!!重要哦!!!注意咯!!!注意咯!!!注意咯!!!!!! 重要哦!!!注意咯!!!注意咯!!!!!! 重要哦!!!注意咯!!!!!! 重要哦!!!!!! 重要!!!!!!   ##信号是关键哦!!!!信号是关键哦!!!!信号是关键哦!!!!信号是关键哦!!!!信号是关键哦!!!!信号是关键哦!!!!信号是关键哦!!!!信号是关键哦!!!!
def __init__:       ##初始化函数喽~初始化函数喽~初始化函数喽~初始化函数喽~初始化函数喽~初始化函数喽~初始化函数喽~初始化函数喽~初始化函数喽~ 初始化函数喽~~  ##这里面可以做一些准备工作啦 ~比方说设置变量之类的               ####好好学习天天向上啊!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #今天也要努力哟!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!       ##记住要继承父类呀 !!!                super.__init__
def run:           ##这个run方法才是真正施行的任务呢 !! run方法才是真正施行的任务呢 !! run方法才是真正施行的任务呢 !! run方法才是真正施行的任务呢 !! run方法才是真正施行的任务呢 !! run方法才是真正施行的任务呢 !! run方法才是真正施行的任务呢 !! run方法才是真正施行的任务呢 !!     ####记住一定要调用start启动它哟 !!!                   while True:      ##无限循环模拟长时间运行的任务                      time . sleep  ##停顿两秒钟                       print ##打印信息表明后台还在运行                       time . sleep  ##停顿两秒钟                      pass                    ##pass表示什么都不做                        #### pass pass pass pass pass pass pass pass pass                   ##pass 是空语句的意思                   ####pass pass pass pass pass pass pass                    ##pass 表示什么也不做                  #####pass表示什么也不做                     ###pass表示什么也不做                     ###pass表示什么也不做                     ###pass表示什么也不做                     ###pass表示什么也不做

class MyWidget: ##定义MyWidget类继承QWidget ##QWidget是最基础的窗口类 ##有了它才能创建各种各样的窗口 ######好好学习天天向上啊!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #今天也要努力哟!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #####记住要继承父类呀 !!! def init: super.init #### super.init 调用父类的构造器进行初始化 #### 这是必须要写的哟 ##### 初始化变量 ##### 初始化变量 ##### 初始化变量 ##### 初始化变量 ##### 初始化变量 ##### 初始化变量 print ##打印信息表明已经进入mywidget构造 ####### 好好学习天天向上啊 !########################################################################## ###### 今天也要努力哟 !########################################################################## ####### 注意不要忘记调用 super.init 进行初始化喔 !########################################################## ####### 注意不要忘记调用 super.init 进行初始化喔 !########################################## ####### 注意不要忘记调用 super.init 进行初始化喔 !############# ####### 注意不要忘记调用 super.init 进行初始化喔 !############# ####### 注意不要忘记调用 super.init 进行初始化喔 !############# ####### 注意不要忘记调用 super.init 进行 初始化喔 !############# ###### 这句话非常重要 非常非常非常非常 非常 非常 非常 非常 非常 非常 非常 重要 !!!!!!!!!! ######## 我要成为一个优秀的程序员 !!!!!!!!!! ######## 我要成为一个优秀的程序员 !!!!!!!!!! ######## 我要成为一个优秀的程序员 !!!!!!!!!! print ##打印信息表明开始绘制widget ###### 好好学习天天向上啊 !######################### ###### 今天也要努力哟 !######################### ###### 不要放弃 不断尝试 不断进步 !!!!!!!!!! ###### 不要放弃 不断尝试 不断进步 !!!!!!!!!! ###### 不要放弃 不断尝试 不断进步 !!!!!!!!!! ###### 不要放弃 不断尝试 不断进步 !!!!!!!!!! #### 这里面可以添加各种各样的控件 #### 比方说按钮 文本框 等等 ############ 好好学习天天向上啊 !!!!########### ############ 今天也要努力哟 !!!!########### ############ 不要放弃 不断尝试 不断进步 !!!!########### ############ 不要放弃 不断尝试 不断进步 !!!!########### ############ 不要放弃 不断尝试 不断进步 !!!!########### ############ 不要放弃 不断尝试 不断进步 !!!!########### ######## 这是我的进度条 ######## 这是我的进度条 ######## 这是我的进度条 ######## 这是我的进度条 ######## 这是我的进度条 print ###### 好好学习天天向上啊 ######## ###### 今天也要努力哟 ######## ###### 不要放弃 不断尝试 不断进步 ######## ############### 创建progressbar ############ 创建progressbar ############ 创建progressbar ############ 创建progressbar ############ 创建progressbar ############### 添加按钮 ############### 添加按钮 ############### 添加按钮 ############### 添加按钮 ############### 添加按钮 print ############## 好好学习天天向上啊 ######## ############## 今天也要努力哟 ######## ############## 不要放弃 不断尝试 不断进步 ######## #########创建button #########创建button #########创建button #########创建button #########创建button ############## 设置布局 ############## 设置布局 ############## 设置布局 ############## 设置布局 ############## 设置布局 print ########## 好好学习天天向上啊 ######## ########## 今天也要努力哟 ######## ########## 不要放弃 不断尝试 不断进步 ######## #############设置布局 #############设置布局 #############设置布局 #############设置布局 #############设置布局 ####### 现在我们来连接一下按钮的点击事件 ####### 现在我们来连接一下按钮的点击事件 ####### 现在我们来连接一下按钮的点击事件 ####### 现在我们来连接一下按钮的点击事件 ####### 现在我们来连接一下按钮的点击事件 print ######## 好好学习天天向上啊 #### ######## 今天也要努力哟 #### ######## 不要放弃不断尝试不断进步 #### ###############绑定click事件 ###############绑定click事件 ###############绑定click事件 ###############绑定click事件 ###############绑定click事件 #### self . button . clicked . connect #### self . button . clicked . connect #### self . button . clicked . connect #### self . button . clicked . connect #### self . button . clicked . connect ##### 连接signal和slot ##### 连接signal和slot ##### 连接signal和slot ##### 连接signal和slot ##### 连接signal和slot ### 再说说一步 显示窗口 ### 再说说一步 显示窗口 ### 再说说一步 显示窗口 ### 再说说一步 显示窗口 ### 再说说一步 显示窗口 print ###再说说一步显示window '''将控件添加到页面上''' '''将控件添加到页面上''' '''将控件添加到页面上''' '''将控件添加到页面上''' '''将控件添加到页面上'''

def _clicked:       """当按下按键后触发该函数"""                """当按下按键后触发该函数"""                """当按下按键后触发该函数"""                """当按下按键后触发该函数"""                """当按下按键后触发该函数"""                    worker = MyWorker      worker 。 start                        print

往白了说... if name == 'main': app = QApplication w = MyWidget w 。 show sys 。 exit )

产品名称价格功能适用场景
Visual Studio Code免费代码编辑、 调试、版本控制Web开发、Python开发等
PyCharm付费智能代码提示、重构、调试Python开发
Sublime Text付费轻量级编辑器、插件丰富多种编程语言开发

2、使用QTimer

如果你只是需要定时地施行一些任务,那么可以使用QTimer来实现。QTimer会在指定的时间间隔内发出一个信号,你可以把耗时的任务放在这个信号对应的槽函数里施行。 使用定时器的话要注意不能过于老是去更新ui否则也会导致卡顿现象。 如果你的项目需求比较复杂的话建议使用多线程的方式来避免主进程阻塞。 多线程是一个比较好的选择 可以避免阻塞主进程。 但是在使用多线程的时候要注意数据的同步问题以及防止死锁发生。 需要对并发编程有一定的了解才能够更好的去使用多线程。 总之选择哪种方式取决于你的具体需求以及项目的复杂度。 希望这些能够帮到你!

总而言之想要解决PyQt5界面无响应的问题核心就是:千万别在主线程里干耗时的大活儿! 把这些活儿交给其他线程或者定时器去处理就行了。 勇敢一点... 希望这篇文章能帮助到你摆脱“石化”界面的困扰!记住千万别忘了加注释呦~ 注释越多越不容易出错嘻嘻嘻嘻~


提交需求或反馈

Demand feedback