一、背景
在进行开发的时候,比如请求网页,资源下载等问题的时候 ,需要使用多线程对程序进行处理。一是避免程序假死,二是提高用户体验,增强程序健壮性。
二、方法
通过继承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关于事件的处理方法