pyqt5教程(十一)多线程防阻塞

一、

当我们设计的界面在处理比较长时间的任务时,就会出现阻塞,出现程序未响应,导致程序停止的情况,例如这个百度图片下载器
所以我们应把主线程与工作线程分离,以免主循环阻塞,造成程序停止响应

二、例子

from PyQt5.QtCore import *  
from PyQt5.QtGui import *  
from PyQt5.QtWidgets import *
import sys

class Example(QWidget):

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

        self.t = 0

        window = QWidget()
        vbox = QVBoxLayout(window)
        #vbox = QVBoxLayout(window)

        lcdNumber = QLCDNumber()
        button = QPushButton("测试")
        vbox.addWidget(lcdNumber)
        vbox.addWidget(button)

        self.timer = QTimer()
        
        button.clicked.connect(self.work)
        self.timer.timeout.connect(self.setTime)

        self.setLayout(vbox)
        self.show()

    def setTime(self):
        self.t += 1
        self.lcdNumber.display(self.t)

    def work(self):
        self.timer.start(10000)
        for i in range(200000000):
            pass
        self.timer.stop()
        
        
if __name__ == "__main__":        
    app = QApplication(sys.argv)
    th = Example()
    sys.exit(app.exec_())

运行这个程序,当我们点击测试,进行较长时间的任务时,程序就无法选中了,最终停止运行。

三、多线程

下面用多线写法解决该问题

from PyQt5.QtCore import *  
from PyQt5.QtGui import *  
from PyQt5.QtWidgets import *
import sys

class Example(QWidget):

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

        self.t = 0

        window = QWidget()
        vbox = QVBoxLayout(window)
        #vbox = QVBoxLayout(window)

        self.lcdNumber = QLCDNumber()
        button = QPushButton("测试")
        vbox.addWidget(self.lcdNumber)
        vbox.addWidget(button)

        self.timer = QTimer()
        
        button.clicked.connect(self.Work)
        self.timer.timeout.connect(self.CountTime)

        self.setLayout(vbox)
        self.show()

    def CountTime(self):
        self.t += 1
        self.lcdNumber.display(self.t)

    def Work(self):
        self.timer.start(1000)
        self.thread = RunThread()
        self.thread.start()
        self.thread.trigger.connect(self.TimeStop)

    def TimeStop(self):
        self.timer.stop()
        print("运行结束用时",self.lcdNumber.value())
        self.t = 0
        

class RunThread(QThread):
    # python3,pyqt5与之前的版本有些不一样
    #  通过类成员对象定义信号对象
    # _signal = pyqtSignal(str)

    trigger = pyqtSignal()
 
    def __init__(self, parent=None):
        super(RunThread, self).__init__()

 
    def __del__(self):
        self.wait() 

    def run(self):
        # 处理你要做的业务逻辑,这里是通过一个回调来处理数据,这里的逻辑处理写自己的方法
        # wechat.start_auto(self.callback)
        # self._signal.emit(msg);  可以在这里写信号焕发
        for i in range(203300030):  
            pass  
        self.trigger.emit()
        # self._signal.emit(msg)

    def callback(self, msg):
        # 信号焕发,我是通过我封装类的回调来发起的
        # self._signal.emit(msg)
        pass

        

if __name__ == "__main__":
    app = QApplication(sys.argv)
    th = Example()
    sys.exit(app.exec_())

从此以后,我们可以开始写很多应用了

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 从哪说起呢? 单纯讲多线程编程真的不知道从哪下嘴。。 不如我直接引用一个最简单的问题,以这个作为切入点好了 在ma...
    Mr_Baymax阅读 2,821评论 1 17
  • Object C中创建线程的方法是什么?如果在主线程中执行代码,方法是什么?如果想延时执行代码、方法又是什么? 1...
    AlanGe阅读 1,777评论 0 17
  • Java多线程学习 [-] 一扩展javalangThread类 二实现javalangRunnable接口 三T...
    影驰阅读 2,986评论 1 18
  • 用markdown写项目需求说明(对内开发版) 项目概述: 这是一个前端使用bootstrap, jQuery框架...
    小小奶狗阅读 3,335评论 0 1
  • 亲爱的大发家人们: 大家晚上好,每次学习活法后都有不同的感悟,每一小节的标题都是鼓舞人心的励志语句,虽然...
    徐书成xsc阅读 1,460评论 0 0