PyQt也給我們提供了這么一個類:QThread
通過繼承它然后重寫里面的 run()
函數,就可以很容易的新建一個線程,達到多線程的任務。
子線程定義:
class myworkthread(QThread): #聲明一個信號,同時返回一個int,什么都可以返回,參數是發送信號時附帶參數的數據類型 finishsignal=QtCore.pyqtSignal(int) def __init__(self,t): #t為創建該實例時傳遞進來的參數,這里需要初始化一下父類的初始化方法,不然會報錯 super(myworkthread, self).__init__() self.t=t #重寫run函數,也就是子線程的執行函數 def run(self): print('子線程開始') #模擬耗時的程序 time.sleep(self.t) print('子線程結束') #子線程結束后,發送一個信號告訴主線程窗口,並附帶參數100 self.finishsignal.emit(100)
創建線程對象,並傳入參數10
然后連接子線程的信號和槽函數
self.mywork=myworkthread(10)
self.mywork.finishsignal.connect(self.workend)
開啟子線程
self.mywork.start()
通過開啟子線程,可以讓耗時的程序在子線程中進行,這樣ui主線程就不會出現假卡死的情況了。
def workend(self,ins): print('get=%d'%ins) self.open = 1
這個函數要定義一個參數傳入接口,因為子線程發過來的信號夾帶了一個參數
源代碼:
ui界面:
# -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'PGUI.ui' # # Created by: PyQt5 UI code generator 5.15.1 # # WARNING: Any manual changes made to this file will be lost when pyuic5 is # run again. Do not edit this file unless you know what you are doing. from PyQt5 import QtCore, QtGui, QtWidgets class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(800, 600) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.centralwidget) self.verticalLayout_2.setObjectName("verticalLayout_2") self.verticalLayout = QtWidgets.QVBoxLayout() self.verticalLayout.setObjectName("verticalLayout") self.horizontalLayout = QtWidgets.QHBoxLayout() self.horizontalLayout.setObjectName("horizontalLayout") self.comboBox = QtWidgets.QComboBox(self.centralwidget) font = QtGui.QFont() font.setFamily("Times New Roman") font.setPointSize(20) self.comboBox.setFont(font) self.comboBox.setObjectName("comboBox") self.horizontalLayout.addWidget(self.comboBox) self.pushButton = QtWidgets.QPushButton(self.centralwidget) font = QtGui.QFont() font.setFamily("Times New Roman") font.setPointSize(20) self.pushButton.setFont(font) self.pushButton.setObjectName("pushButton") self.horizontalLayout.addWidget(self.pushButton) self.verticalLayout.addLayout(self.horizontalLayout) self.horizontalLayout_2 = QtWidgets.QHBoxLayout() self.horizontalLayout_2.setObjectName("horizontalLayout_2") self.verticalLayout_3 = QtWidgets.QVBoxLayout() self.verticalLayout_3.setObjectName("verticalLayout_3") self.label_2 = QtWidgets.QLabel(self.centralwidget) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.label_2.sizePolicy().hasHeightForWidth()) self.label_2.setSizePolicy(sizePolicy) font = QtGui.QFont() font.setFamily("Times New Roman") font.setPointSize(24) self.label_2.setFont(font) self.label_2.setAlignment(QtCore.Qt.AlignCenter) self.label_2.setObjectName("label_2") self.verticalLayout_3.addWidget(self.label_2) self.lineEdit = QtWidgets.QLineEdit(self.centralwidget) font = QtGui.QFont() font.setFamily("Times New Roman") font.setPointSize(20) self.lineEdit.setFont(font) self.lineEdit.setObjectName("lineEdit") self.verticalLayout_3.addWidget(self.lineEdit) self.horizontalLayout_2.addLayout(self.verticalLayout_3) self.verticalLayout_4 = QtWidgets.QVBoxLayout() self.verticalLayout_4.setObjectName("verticalLayout_4") self.label_3 = QtWidgets.QLabel(self.centralwidget) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.label_3.sizePolicy().hasHeightForWidth()) self.label_3.setSizePolicy(sizePolicy) font = QtGui.QFont() font.setFamily("Times New Roman") font.setPointSize(24) self.label_3.setFont(font) self.label_3.setAlignment(QtCore.Qt.AlignCenter) self.label_3.setObjectName("label_3") self.verticalLayout_4.addWidget(self.label_3) self.lineEdit_2 = QtWidgets.QLineEdit(self.centralwidget) font = QtGui.QFont() font.setFamily("Times New Roman") font.setPointSize(20) self.lineEdit_2.setFont(font) self.lineEdit_2.setObjectName("lineEdit_2") self.verticalLayout_4.addWidget(self.lineEdit_2) self.horizontalLayout_2.addLayout(self.verticalLayout_4) self.verticalLayout.addLayout(self.horizontalLayout_2) self.horizontalLayout_3 = QtWidgets.QHBoxLayout() self.horizontalLayout_3.setObjectName("horizontalLayout_3") self.pushButton_3 = QtWidgets.QPushButton(self.centralwidget) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.pushButton_3.sizePolicy().hasHeightForWidth()) self.pushButton_3.setSizePolicy(sizePolicy) font = QtGui.QFont() font.setFamily("Times New Roman") font.setPointSize(20) self.pushButton_3.setFont(font) self.pushButton_3.setObjectName("pushButton_3") self.horizontalLayout_3.addWidget(self.pushButton_3) self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget) font = QtGui.QFont() font.setFamily("Times New Roman") font.setPointSize(20) self.pushButton_2.setFont(font) self.pushButton_2.setObjectName("pushButton_2") self.horizontalLayout_3.addWidget(self.pushButton_2) self.verticalLayout.addLayout(self.horizontalLayout_3) self.textBrowser = QtWidgets.QTextBrowser(self.centralwidget) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.textBrowser.sizePolicy().hasHeightForWidth()) self.textBrowser.setSizePolicy(sizePolicy) font = QtGui.QFont() font.setFamily("Times New Roman") font.setPointSize(16) self.textBrowser.setFont(font) self.textBrowser.setObjectName("textBrowser") self.verticalLayout.addWidget(self.textBrowser) self.verticalLayout_2.addLayout(self.verticalLayout) MainWindow.setCentralWidget(self.centralwidget) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) self.pushButton.setText(_translate("MainWindow", "開啟串口")) self.label_2.setText(_translate("MainWindow", "電壓設定值/kV")) self.label_3.setText(_translate("MainWindow", "電流設定值/mA")) self.pushButton_3.setText(_translate("MainWindow", "高壓開關")) self.pushButton_2.setText(_translate("MainWindow", "讀取電壓電流"))
主代碼:
from sys import argv,exit import serial from PyQt5 import QtCore from PyQt5.QtCore import QTimer,QThread from PyQt5.QtWidgets import QApplication, QMainWindow from modbus_tk import modbus_rtu import PGUI import time class my_mainwindow(): def __init__(self): # PyQt5中,每個應用程序都必須實例化一個QApplication(): app = QApplication(argv) self.my_MainWindow = QMainWindow() self.my_ui = PGUI.Ui_MainWindow() self.my_ui.setupUi(self.my_MainWindow) #################################################################### self.open = 1 self.timer = QTimer() self.timer.timeout.connect(self.showTime) self.timer.start(1000) self.mywork=myworkthread(10) self.mywork.finishsignal.connect(self.workend) ##################################################################### self.my_MainWindow.show() exit(app.exec_()) def workend(self,ins): print('get=%d'%ins) self.open = 1 def showTime(self): if self.open==1: print('time') self.mywork.start() print('timeover') self.open=0 class myworkthread(QThread): #聲明一個信號,同時返回一個int,什么都可以返回,參數是發送信號時附帶參數的數據類型 finishsignal=QtCore.pyqtSignal(int) def __init__(self,t): #t為創建該實例時傳遞進來的參數,這里需要初始化一下父類的初始化方法,不然會報錯 super(myworkthread, self).__init__() self.t=t #重寫run函數,也就是子線程的執行函數 def run(self): print('子線程開始') #模擬耗時的程序 time.sleep(self.t) print('子線程結束') #子線程結束后,發送一個信號告訴主線程窗口,並附帶參數100 self.finishsignal.emit(100) if __name__=="__main__": my_mainwindow()