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


    渣渣用法,请等待我心情好的时候更新。

    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窗口无卡顿了。

  • 相关阅读:
    关于异步IO与同步IO的写操作区别
    慢慢开始记录一些技术心得吧
    写了placement new就要写placement delete
    关于针对class自定义new操作符失败的函数处理
    operator->和operator->*
    关于继承中的拷贝构造函数
    关于g++编译模板类的问题
    关于互斥锁,条件变量的内核源码解析
    关于sigwait
    观察者设计模式
  • 原文地址:https://www.cnblogs.com/jackadam/p/8302442.html
Copyright © 2020-2023  润新知