pyqt5 使用 QTimer, QThread, pyqtSignal 实现自动执行,多线程,自定义信号触发

技术知识
0 2036
小师傅 小师傅2021-12-15
积分:2397

1.第一个例子

1.1 先看mainwindow.py

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(640, 320)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.textBrowser = QtWidgets.QTextBrowser(self.centralwidget)
        self.textBrowser.setGeometry(QtCore.QRect(0, 0, 320, 320))
        self.textBrowser.setObjectName("textBrowser")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(450, 150, 75, 23))
        self.pushButton.setObjectName("pushButton")
        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)
        self.pushButton.clicked.connect(MainWindow.start)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushButton.setText(_translate("MainWindow", "开始"))

定义了一个窗口UI_MainWindow,有一个textBrowser,有一个pushButton

pushButton点击连接到MainWindow.start

1.2 看main.py

import sys, time
from PyQt5 import QtWidgets
from PyQt5.QtCore import QTimer, QThread, pyqtSignal
from mainwindow import Ui_MainWindow


class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent=parent)
        self.setupUi(self)

    def start(self):
        time.sleep(2)
        self.textBrowser.append('test1')


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

简单的继承UI_MainWindow,并且定义了MainWindow.start,延迟两秒给textBrowser写进test

2.引入QTimer

QTimer是一个定时任务,可以在指定的时间运行制定的函数,电子钟示例都用的它。

我要用它来实现窗口加载完毕后就自动执行的任务,一般是程序的自检任务。

2.1看main.py

import sys, time
from PyQt5 import QtWidgets
from PyQt5.QtCore import QTimer, QThread, pyqtSignal
from mainwindow import Ui_MainWindow


class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent=parent)
        self.setupUi(self)
        # 初始化一个定时器
        self.timer = QTimer(self)
        # 定义时间超时连接start_app
        self.timer.timeout.connect(self.start)
        # 定义时间任务是一次性任务
        self.timer.setSingleShot(True)
        # 启动时间任务
        self.timer.start()

    def start(self):
        time.sleep(2)
        self.textBrowser.append('test1')


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

增加的4行就能实现启动即执行。

但是问题是,都执行完MainWindow.start,窗体才显现出来。这个体验可是真差了。

3.引入QThread

QThread是一个多线程调度器,和python的threading性质一样,看名字都像。

3.1 看main.py

import sys, time
from PyQt5 import QtWidgets
from PyQt5.QtCore import QTimer, QThread, pyqtSignal
from mainwindow import Ui_MainWindow


class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent=parent)
        self.setupUi(self)
        # 初始化一个定时器
        self.timer = QTimer(self)
        # 定义时间超时连接start_app
        self.timer.timeout.connect(self.start)
        # 定义时间任务是一次性任务
        self.timer.setSingleShot(True)
        # 启动时间任务
        self.timer.start()
        # 实例化一个线程
        self.work = WorkThread()
        # 多线程的信号触发连接到UpText
        self.work.trigger.connect(self.UpText)

    def start(self):
        # time.sleep(2)
        # self.textBrowser.append('test1')
        # 启动另一个线程
        self.work.start()

    def UpText(self, str):
        time.sleep(2)
        self.textBrowser.append('test2')


class WorkThread(QThread):
    # 定义一个信号
    trigger = pyqtSignal(str)

    def __int__(self):
        # 初始化函数,默认
        super(WorkThread, self).__init__()

    def run(self):
        time.sleep(5)
        # 等待5秒后,给触发信号,并传递test
        self.trigger.emit('test2')


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

3.2讲解一下对这个程序的理解:

窗口启动后,用QTimer启动一个一次性任务MainWindow.start

MainWindow.start,则是通过QThread启动另一个线程   WrokThread.run

WrokThread.run触发一个信号WrokThread.tragger,并传入字符串‘test2’

MainWindow中的work是实例化的WrokThread

work.trigger连接到MainWindow.UpText

执行了MainWindow.UpText,就更新了textBrowser

由于是多线程执行,一个线程再展示GUI窗口,另一个线程在执行WrokThread.run,所以GUI窗口无卡顿了。


精选帖子
Android 可可影视 v3.3.6无广告纯净版 3091
Android QQ音乐 v11.3.7 定制版解锁免费听歌无广告版 3672
Android 草图大师SKP v1.5 解锁会员版 9024
Android OmoFun追漫神器 v4.2.1 无广告绿色版 6066
AdobeGenP Adobe全家桶系列激活工具 v3.5.0/3.4.14.1 绿色版 6647
Android 七猫免费听书 v1.4 解锁高级版 5055
超良心的抢票神器——Bypass1.16 4787
Android 玲珑加速器 v6.10.9.40 解锁无限时间 3441
Android 大师兄影视 v3.3.8 去广告会员版 2568
热门帖子
一键激活Win系统和Office办公软件,最强电脑激活KMS HUE工具,免费永久可用,支持win系统使用 58
得间免费小说 v5.5.8.1 免费网文追书APP 54
酷我音乐 v12.1.8.2 无损音乐播放APP 去广告解锁会员版 51
ChatGPT+Codex电脑自动化课:环境搭建×三大核心实战×全场景应用拓展×AI自主操控电脑×零基础上手 51
豆丁视频 v3.3.0 高清影视播放 免费追剧APP 46
蚂蚁视界 v6.7.0 高清影视追剧APP 全品类视频播放软件 45