• pyqt5使用多线程避免程序假死


    一、背景

    在进行开发的时候,比如请求网页,资源下载等问题的时候 ,需要使用多线程对程序进行处理。一是避免程序假死,二是提高用户体验,增强程序健壮性。

    二、方法

    通过继承Qthread的方法,重写run函数进行处理。处理的流程如下图

    2.1 构建线程方法

    通过继承Qthread编写自己的线程方法

    # 这里编写一个请求网站资源的多线程方法
    class Thread(QThread):
        # 设置信号量,用于线程返回信息的处理
        signal = pyqtSignal(str)
    
        def __init__(self, url=None):
            super(Thread, self).__init__()
            # 实现参数的传递
            self.url = url
        
        def run(self):
            """  重构的run函数  """
            #  需要多线程的方法,这里是一个视频下载的方法
            get_url(self.url)
            # 将线程处理的信息返回给调用的槽函数,可以实现加锁和解锁的目的
            self.signal.emit()

    2.2 线程方法的时候

    # 在pyqt中使用刚刚创建的线程方法
    # 核心部分
    # 注:这里使用oop的编程思想,因此输入的文本直接通过文本框的方法获取到输入的结果
    
    def button_ui(self):
        # 确定按钮按钮出发线程事件
        self.qbtn.clicked.connect(self.event_confirm)
        # 按钮布局
        self.qbtn.resize(self.qbtn.sizeHint())
        self.qbtn.move(189, 400)
    
    # 函数事件
    def event_confirm(self):
        # 设置按钮不可用,锁定状态
        self.qbtn.setEnabled(False)
        #  获取参数
        content_text = self.qtb.toPlainText()
        self.thread.url = content_text
        # 启动线程
        self.thread.start()
        # 处理完之后的回调,
        self.thread.signal.connect(self.set_btn)
    
    def set_btn(self):
        # 将按钮标签的状态回滚
        self.qbtn.setEnabled(True)

    2.3 实际例子

    这里实现一个从网站下载视频的例子,总代码如下:

    import sys
    from PyQt5.QtCore import QCoreApplication, QThread, pyqtSignal
    from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLabel, QPlainTextEdit
    from PyQt5.QtGui import QIcon
    
    class Thread(QThread):
        signal = pyqtSignal(str)
    
        def __init__(self, url=None):
            super(Thread, self).__init__()
            self.url = url
    
        def run(self):
         # 线程使用的方法 get_url(self.url) self.signal.emit()
    class Example(QWidget): def __init__(self): super(QWidget, self).__init__() self.qbtn = QPushButton('确定', self) self.thread = Thread() self.qtb = QPlainTextEdit(self, ) self.init_ui() # 界面绘制交给InitUi方法 def button_ui(self): # 退出按钮 qbtn = QPushButton('退出', self) qbtn.clicked.connect(QCoreApplication.instance().quit) qbtn.resize(qbtn.sizeHint()) qbtn.move(689, 400) # 标签 qlab = QLabel("输入网址", self) qlab.resize(qlab.sizeHint()) qlab.move(200, 50) # 输入框 self.qtb.resize(self.qtb.sizeHint()) self.qtb.move(260, 70) # 确定按钮 self.qbtn.clicked.connect(self.event_confirm) self.qbtn.resize(self.qbtn.sizeHint()) self.qbtn.move(189, 400) def event_confirm(self): self.qbtn.setEnabled(False) content_text = self.qtb.toPlainText() self.thread.url = content_text print(self.thread.url) self.thread.start() # print(content_text) self.thread.signal.connect(self.set_btn) # content_text = self.qtb.toPlainText() # self.thread.trigger.connect(get_url(content_text)) # self.thread.start() def set_btn(self): self.qbtn.setEnabled(False) def init_ui(self): self.button_ui() # 设置窗口的位置和大小 self.setGeometry(510, 297, 863, 473) # 设置窗口的标题 self.setWindowTitle('视频获取') # 设置窗口的图标,引用当前目录下的web.png图片 self.setWindowIcon(QIcon('web.png')) # 显示窗口 self.show() if __name__ == '__main__': # 创建应用程序和对象 app = QApplication(sys.argv) ex = Example() sys.exit(app.exec_())

    三、总结

    多线程的使用对于实际的开发很重要,这里列举了一个实际的例子,可以据此写出更加复杂的功能。

    参考

    这里列举一些学习过程中有用的资源。

    博客园Qthread使用

    知乎Qthread多线程多种方法介绍

    PyQt关于事件的处理方法

  • 相关阅读:
    Python中的返回函数与闭包
    Python的高阶函数小结
    Python的生成器Generator小结
    Vim插件YCM的安装
    用Vundle管理Vim插件
    声卡(Sound Card)基本概念
    Linux中Source的用法
    js 的执行过程
    mongoose@4.5.2的eachAsync bug
    [mongodb] MMAP 和wiredTiger 的比较
  • 原文地址:https://www.cnblogs.com/future-dream/p/14749132.html
Copyright © 2020-2023  润新知