pyqt5学习笔记(三)——多线程的使用

1、问题的出现

当按钮控件按下后,如果操作比较耗时,就会出现界面假死、卡死的现象,如果要想在这个过程中将运行过程中的内容打印在文本控件上,此时也不会出现内容。

现在模拟一下,在按钮的槽函数里面添加一个休眠函数,添加一个for循环,循环一次休眠1秒,模拟耗时函数,每次循环之后将信息打印在文本控件中,同时信息也在后台打印一下。

本次演示需要两个控件,一个pushButton,一个textEdit(记得将ui文件转化为py文件)

pyqt5学习笔记(三)——多线程的使用_第1张图片

添加信号和槽函数

pyqt5学习笔记(三)——多线程的使用_第2张图片

  # 信号
 self.pushButton.clicked.connect(self.on_click_start)


    # 槽函数
    def on_click_start(self):
        for i in range(10):
            time.sleep(1)
            print('第{}次循环'.format(i+1))
            self.textEdit.append('第{}次循环'.format(i+1))

运行效果

pyqt5学习笔记(三)——多线程的使用_第3张图片

可以看到,当点击按钮一小会之后,主界面就出现未响应的状态,如果此时不停点击主界面就会卡死。

在10次循环中,每次后台都可以打印信息,但是每次循环的内容却不打印在文本控件上,直到循环结束才出现在文本控件上,这是因为整个程序是一个单线程,只能注意一件事情,在执行按钮点击的事件的时候,主界面就照顾不到了,所以主界面会出现未响应,控件上也显示不出来信息

2、解决办法

使用多线程,开辟一个子线程,将耗时的任务放到子线程,主线程继续刷新主界面

需要使用QThread类

这里我们新建一个py文件,在文件中导入OThread类(多线程类),pyqtSignal(信号类),编写一个类用来继承QThread

pyqt5学习笔记(三)——多线程的使用_第4张图片

Thread.py

from PyQt5.QtCore import QThread, pyqtSignal
import time


class MyThread(QThread):
    mySignal = pyqtSignal(int) # 实例化一个信号

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

    def run(self):
        for i in range(10):
            time.sleep(1) # 每次循环休眠一秒,模拟耗时操作
            self.mySignal.emit(i)  # 发射信号

我们将循环的的耗时代码放在run()方法中

mySignal = pyqtSignal(int) 实例化了一个信号,用来将当前的值做为信号发射到主程序中,括号里得类型根据实际需求来,我这里传得是数字,所以用的int

在主程序中接受信号

pyqt5学习笔记(三)——多线程的使用_第5张图片

run.py

from untitled import Ui_MainWindow
from PyQt5.QtWidgets import *
from Thread import *
import sys


class Run(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super(Run, self).__init__()
        self.setupUi(self)
        self.myThraed = MyThread() # 实例化多线程类
        # 信号
        self.pushButton.clicked.connect(self.on_click_start)
        self.myThraed.mySignal.connect(self.accept_signal)

    # 槽函数
    def on_click_start(self):
        self.myThraed.start()

    # 接受信号的值,将该值显示在控件上
    def accept_signal(self, int):
        self.textEdit.append('第{}次循环'.format(int+1))


if __name__ == '__main__':
    app = QApplication(sys.argv)
    run = Run()
    run.show()
    sys.exit(app.exec_())

运行效果

pyqt5学习笔记(三)——多线程的使用_第6张图片

此时,运行的时候就可以同时显示内容,而且点击主界面也不会卡死

3、在子程序中获取文本控件的内容

有时候我们需要在子线程的run()方法中获取文本控件的内容,此时就需要在实例化线程的时候将主类做为参数传入,在子线程的类中实例化

这里添加一个lineEdit控件,在按钮点击事件中,给这个控件设文本内容,在子线程中读取这个控件的文本内容并后台打印

在上面的代码做修改

在run.py中

pyqt5学习笔记(三)——多线程的使用_第7张图片

在Thread.py中,做如下修改

pyqt5学习笔记(三)——多线程的使用_第8张图片

运行效果

可以看到,给lineEdit设置文本内容后,在子线程的run方法中获取到了控件的内容打印到了后台

pyqt5学习笔记(三)——多线程的使用_第9张图片

你可能感兴趣的:(pyqt5入门,python,多线程,可视化,pyqt5)