6. PyQt5 中的多线程的使用(上)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chouzhou9701/article/details/88716205

专栏地址 ʅ(‾◡◝)ʃ


这一节引入了多线程这个非常重要概念, 在我认为多线程的重要性是紧紧次于信号与槽函数的, 因为在平时经常使用

1. 为什么要用多线程

先看下面这一个示例代码
6.1

from form import Ui_Form
from PyQt5.QtWidgets import *
import sys
import time

class MyWin(QWidget,Ui_Form):
    """docstring for Mywine"""
    def __init__(self):
        super(MyWin, self).__init__()
        self.setupUi(self)

    def test(self): # 这里test就是槽函数, 当点击按钮时执行 test 函数中的内容, 注意有一个参数为 self
        for i in range(10):
            self.pushButton.setText(str(i))
            time.sleep(1)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    mywin = MyWin() # 实例化一个窗口小部件
    mywin.setWindowTitle('Hello world!') # 设置窗口标题
    mywin.show() #显示窗口
    sys.exit(app.exec())

代码很简单, 就是点击按钮后, 将按钮的内容设置为 0, 然后等待一秒后 再设置 为1, 如此循环, 一直设置到 9, 这个过程结束
但是在实际运行的过程中点击按钮后就没有反应了, 一直等待 10 秒后直接将按钮的内容设置为 9

这是因为图形化界面必须等待代码中的 test() 槽函数执行完毕后再更新图形话界面的内容, 所以直到 test() 函数执行完毕后 按钮的内容只会被设置为 9, 而没有中间的设置过程

当然在实际的软件开发的时候阻塞的时间可能会更长, 想象一下如果你制作一个下载器有一个进度条, 开始时进度还是0 ,过了很长时间突然件进度突然跑满了, 会让用户有一种软件卡住的错觉, 这个时候我们就需要使用 PyQt5 的多线程了

2. 怎么使用多线程

python 编程基础的人可能第一个想到的是 threading 这个库
但这里不是用到 threading , 而是 PyQt5 中的多线程类
示例代码:
6.2

from form import Ui_Form
from PyQt5.QtWidgets import *
from PyQt5.QtCore import QThread, pyqtSignal
import sys
import time

class MyWin(QWidget,Ui_Form):
    """docstring for Mywine"""
    def __init__(self):
        super(MyWin, self).__init__()
        self.setupUi(self)
        self.mythread = MyThread() # 实例化自己建立的任务线程类
        self.mythread.signal.connect(self.callback) #设置任务线程发射信号触发的函数

    def test(self): # 这里test就是槽函数, 当点击按钮时执行 test 函数中的内容, 注意有一个参数为 self
        self.mythread.start() # 启动任务线程

    def callback(self,i): # 这里的 i 就是任务线程传回的数据
        self.pushButton.setText(i)

class MyThread(QThread): # 建立一个任务线程类
    signal = pyqtSignal(str) #设置触发信号传递的参数数据类型,这里是字符串
    def __init__(self):
        super(MyThread, self).__init__()

    def run(self): # 在启动线程后任务从这个函数里面开始执行
        for i in range(10):
            self.signal.emit(str(i)) #任务线程发射信号用于与图形化界面进行交互
            time.sleep(1)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    mywin = MyWin() # 实例化一个窗口小部件
    mywin.setWindowTitle('Hello world!') # 设置窗口标题
    mywin.show() #显示窗口
    sys.exit(app.exec())

可能看到这部分, 感觉很乱多出了很多代码, 每行代码的意义注释我都已经进行了详细的标注
这里简单说一下建立任务线程的步骤:

  1. 导入需要的 的类 from PyQt5.QtCore import QThread, pyqtSignal 其实为了简单你也可这样写 from PyQt5.QtCore import *
  2. 编写任务线程的类 这里的任务线程类是 MyThread 并让它继承 QThread , 并设置触发信号传递的数据类型, 编写 run()函数, 设置触发
  3. MyWin 类中的初始化函数中, 初始化一个任务线程, 设置任务线程触发后接受的函数
  4. 在合适的位置启动 任务线程, 比如这里我是在点击按钮后启动的任务线程
  5. 编写任务线程触发的槽函数 callback()

其实刚学到这里的时候, 我也很懵, 但是很多都是固定的写法, 只要注意上面的几个关键的地方就可以了
启动程序后, 按钮的内容从 0 自增加到 9
这里要注意的是 传递信号必须事先定义好数据类型, 而传递过去的类型必须是已经定义好的数据类型
这里我只说了 任务线程 传递给图形化界面数据(代码中数据是 0, 1, 2, 3…9), 而没有图形界面传递给任务线程数据
下一节说明 图形化界面如何传递给任务线程数据

猜你喜欢

转载自blog.csdn.net/chouzhou9701/article/details/88716205