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

技术知识
0 2132
小师傅 小师傅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无广告纯净版 3241
Android QQ音乐 v11.3.7 定制版解锁免费听歌无广告版 3821
Android 草图大师SKP v1.5 解锁会员版 9150
Android OmoFun追漫神器 v4.2.1 无广告绿色版 6187
AdobeGenP Adobe全家桶系列激活工具 v3.5.0/3.4.14.1 绿色版 6779
Android 七猫免费听书 v1.4 解锁高级版 5160
超良心的抢票神器——Bypass1.16 4898
Android 玲珑加速器 v6.10.9.40 解锁无限时间 3531
Android 大师兄影视 v3.3.8 去广告会员版 2667
热门帖子
Grok 4.6 代理自动制作视频!从提示词到成片全流程详细分享|AI Agent 实操分享 65
不会写作也能干!AI 全自动生成文稿,一单纯赚 900+,全套接单模板直接搬! 64
2个月收入6705元,最新平台小众赛道,全程Ai操作人人可做! 59
金牌影院 v7.0.1 高清影视追剧软件APP 57
快手短剧挂载 全托管 单号月入200-600 可批量 3-5分钟搞定 53
WorkBuddy全能AI工作台实战课:从3步搭建AI工作台到Skill技能、知识库与办公自动化,系统掌握全场景应用 51
淘宝闪购一分购拉新玩法-更新0911:20元每单+大厂高价项目,掌握素材制作、精准引流与用户下单转化方法 48
全自动番茄挂机玩法,日入300+边阅读边积累,轻松获得额外收入 48
Workbuddy技能变现实战教程:AI批量做内容+经验包装成产品+自动完成交付,一人跑通轻资产创业模式 46