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

2021/5/12 20:27:19

本文主要是介绍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关于事件的处理方法



这篇关于pyqt5使用多线程避免程序假死的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程