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窗口無卡頓了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM