PyQt界面阻塞卡死问题的解决

 更新时间:2024年01月03日 09:15:48   作者:机器人迈克猫  
当用PyQt5开发一个GUI界面 ,需要执行业务逻辑时,后台逻辑执行时间长,界面就容易出现卡死、未响应等问题,本文主要介绍了PyQt界面阻塞卡死问题的解决

任何同学在使用类似PyQt(或者C#开发winform,WPF)开发带界面的软件的刚开始阶段,都会碰到界面卡死软件崩溃的问题。

就比如以下这段代码

import sys

from PyQt5.Qt import *

import time


class Window(QWidget):

    def __init__(self):
        super().__init__()  
        self.setWindowTitle("更新界面案例")
        self.resize(300, 200)
        self.move(400, 250)

    def setup_ui(self):
        self.label = QLabel(self)
        self.label.setText("当前人数: 100")
        self.label.move(100, 50)

        self.btn1=QPushButton(self)
        self.btn1.setText("按钮1")
        self.btn1.move(50,125)
        self.btn1.clicked.connect(self.btn1_method)

        self.btn2=QPushButton(self)
        self.btn2.setText("按钮2")
        self.btn2.move(165,125)
    

    def btn1_method(self):
        
        # 以下为一通耗时操作,比如查询数据库
        time.sleep(10)

        #根据上面逻辑操作的结果,更新界面
        self.label.setText("当前人数: 200")
        

if __name__ == "__main__":
    app = QApplication(sys.argv)

    window = Window()  
    window.setup_ui() 
    window.show()  

    sys.exit(app.exec_())

运行之后,点击按钮1,会发现界面卡死了,有的人着急再点击几下界面,软件就直接芭比Q了。

 造成这个现象的原因是,本来软件界面是一直占着主进程的,点击按钮之后,如果按钮执行的是长时间的操作,这个操作就把主进程占住不放了,没有进程来处理软件界面,这个时候界面就会卡死。

所以解决问题的思路就是主进程还是给软件界面,把按钮耗时的工作交给线程去处理,方法有很多,这里用PyQt中的QThread举例

class btn2Thread(QThread):

    def __init__(self):
        super(btn2Thread,self).__init__()

    def run(self):

        # 以下为一通逻辑操作,比如查询数据库
        time.sleep(10)
        
        # 更新主界面,但是在QThread里找不到主界面的控件

但是这里又会出现一个问题,在执行完复杂操作去更新界面的时候,发现在QThread找不到主界面的控件,就不能更新主界面了。

解决方法是,在线程里找不到主界面的控件,在主界面的进程里我们是可以找到控件的,那我们就把线程处理完的结果通过信号发送到主界面的进程,主界面在接收到这个消息后,根据接收到的消息更新主界面

class btn2Thread(QThread):
    # 声明一个信号
    update_ui_signal=pyqtSignal(str)

    def __init__(self):
        super(btn2Thread,self).__init__()

    def run(self):

        # 以下为一通逻辑操作,比如查询数据库
        time.sleep(10)

        # 根据查询数据库的结果,比如查询到200,发送信号
        self.update_ui_signal.emit((str(200)))

至此解决了界面卡死的问题,以下为完整代码

import sys

from PyQt5.Qt import *

import time

class btn2Thread(QThread):
    # 声明一个信号
    update_ui_signal=pyqtSignal(str)

    def __init__(self):
        super(btn2Thread,self).__init__()

    def run(self):

        # 以下为一通逻辑操作,比如查询数据库
        time.sleep(10)

        # 根据查询数据库的结果,比如查询到200,发送信号
        self.update_ui_signal.emit((str(200)))

class Window(QWidget):

    def __init__(self):
        super().__init__()  
        self.setWindowTitle("更新界面案例")
        self.resize(300, 200)
        self.move(400, 250)

    def setup_ui(self):
        self.label = QLabel(self)
        self.label.setText("当前人数: 100")
        self.label.move(100, 50)

        self.btn1=QPushButton(self)
        self.btn1.setText("按钮1")
        self.btn1.move(50,125)
        self.btn1.clicked.connect(self.btn1_method)

        self.btn2=QPushButton(self)
        self.btn2.setText("按钮2")
        self.btn2.move(165,125)
        self.btn2.clicked.connect(self.btn2_method)

    def btn1_method(self):
        
        # 以下为一通逻辑操作
        time.sleep(10)

        #根据上面逻辑操作的结果,更新界面
        self.label.setText("当前人数: 200")
        

    def btn2_method(self):
        self.btn2Thread_object=btn2Thread()
        self.btn2Thread_object.start()
        self.btn2Thread_object.update_ui_signal.connect(self.update_label)

    def update_label(self,str1):
        self.label.setText("当前人数: %s"%(str1))




if __name__ == "__main__":
    app = QApplication(sys.argv)

    window = Window()  
    window.setup_ui() 
    window.show()  

    sys.exit(app.exec_())

到此这篇关于PyQt界面阻塞卡死问题的解决的文章就介绍到这了,更多相关PyQt界面阻塞卡死内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

相关文章

  • NumPy random.choice()函数的使用小结

    NumPy random.choice()函数的使用小结

    随机采样 是一个非常常见的操作,NumPy提供的numpy.random.choice() 函数让我们可以方便地从数组或序列中随机选取元素,本文将带深入介绍 numpy.random.choice() 的功能及常见实战案例,感兴趣的可以了解一下
    2026-01-01
  • 利用python修改json文件的value方法

    利用python修改json文件的value方法

    今天小编就为大家分享一篇利用python修改json文件的value方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-12-12
  • python导包的几种方法(自定义包的生成以及导入详解)

    python导包的几种方法(自定义包的生成以及导入详解)

    这篇文章主要介绍了python导包的几种方法(自定义包的生成以及导入详解),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-07-07
  • 解决Python传递中文参数的问题

    解决Python传递中文参数的问题

    这篇文章主要介绍了解决Python传递中文参数的问题的相关资料,需要的朋友可以参考下
    2015-08-08
  • PyTorch之nn.ReLU与F.ReLU的区别介绍

    PyTorch之nn.ReLU与F.ReLU的区别介绍

    这篇文章主要介绍了PyTorch之nn.ReLU与F.ReLU的区别介绍,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-06-06
  • python scrapy重复执行实现代码详解

    python scrapy重复执行实现代码详解

    这篇文章主要介绍了python scrapy重复执行实现代码详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • 从入门到精通:玩转Python Fire库

    从入门到精通:玩转Python Fire库

    想快速打造属于你的Python GUI应用吗?抛开复杂的代码,用Python Fire库就能轻松实现!本指南将引领你从零起步,驾驭Python Fire的强大功能,让编程既简单又高效,准备好了吗?让我们开始玩转Python Fire,开启你的编程冒险吧!
    2024-02-02
  • pygame实现简单五子棋游戏

    pygame实现简单五子棋游戏

    这篇文章主要为大家详细介绍了pygame实现简单五子棋游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下<BR>
    2022-01-01
  • 让Python脚本暂停执行的几种方法(小结)

    让Python脚本暂停执行的几种方法(小结)

    这篇文章主要介绍了让Python脚本暂停执行的几种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-07-07
  • 从基础到高级详解Python函数返回多个值的完全指南

    从基础到高级详解Python函数返回多个值的完全指南

    在现代Python编程中,返回多个值的函数设计模式已被广泛应用于​​数据处理​​、​​API开发​​、​​科学计算​​等众多领域,下面小编就为大家详细介绍一下吧
    2025-10-10

最新评论