pyqt5记录笔记之多线程

@ pyqt5多线程
pyqt5运行程序时,如果程序消耗时间过久,就会出现界面假死的情况,解决方法可以将耗时过久的程序放到线程中。

一,重写QThread类

#需要加载模块中的QThread和pyqtSignal
from PyQt5.QtCore import QThread,pyqtSignal

class MyThread(QThread):
	Signal1 = pyqtSignal(str)		#自定义触发信号
	def __init__(self, count):
		super().__init__()
 		self.count = count
 		
	def run(self):				#run方法重写
		for i in range(self.count):
			self.Signal1.emit(str(i))	#发送信号,触发槽函数
			time.sleep(1)	#添加时延

1,自定义触发信号

pyqtSignal()自定义触发信号,为类变量 ,参数类型可以是str,int,None,list等多种形式,表示触发的信号类型。

2,run()

在自定义的线程类中重写run()方法。run()方法中写线程功能,一般是耗时较久或者重复执行的功能。

3,emit()

emit()用于触发槽函数,参数类型与pyqtSignal()的参数类型一样,表示触发信号的类型。emit()的参数会传给此信号连接的槽函数。

4,论时延的重要性

初看别人的介绍时,一直不理解为什么都要在最后添加时延,直到自己的程序执行时,添加多线程后仍然出现界面假死才明白时延的重要性。
如果线程函数触发槽函数为循环触发,且每次循环中运行时间过短的话,线程频繁触发槽函数,访问主界面的间隔过短,会表现为主界面一直运行,界面卡顿。

二,线程执行

self.Thread1 = MyThread(10)	#创建线程实例
self.Thread1.Signal1.connect(self.threadFunc)	#自定义的信号连接到槽函数
self.Thread1.start()	#开始执行

1,首先进行实例化,创建一个线程实例,并对其进行初始化。
2,线程执行时依然遵循qt的信号与槽函数机制,通过重写Qthread类中自定义的触发信号,线程触发Signal1信号,连接到槽函数threadFunc,槽函数与界面进行交互,即将功能与UI分开,run()函数中执行功能部分,槽函数中执行界面交互。线程与槽函数传递参数是通过emit()触发函数传递的。
3,执行start()时,线程开始执行,将自动执行线程类中的run()函数。

三,时序

主线程执行,执行到子线程的start(),主线程继续执行,子线程自动跳到run()函数,执行子线程功能。直到emit()触发信号到threadFun槽函数,与UI交互,返回到主线程。此时,若主线程代码段执行完毕,则执行槽函数,主线程代码段未执行完,等到主线代码段程执行完,再执行槽函数。

主线程
子线程
主线程代码段执行完才执行
开始
主线程执行
代码段...
子线程创建
主线程代码段
start
槽函数
run
emit

四,代码示例

贴一段自己随便写的代码记录

import time
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import QThread,pyqtSignal
from PyQt5.QtSerialPort import QSerialPortInfo
from TestUI import Ui_Form  #UI

#自定义线程类省略

#界面交互
class QmyMainWindow(QWidget):
	def __init__(self):
		QWidget.__init__(self)
	 	 # self.setupUi()
	 	 self.Ui_Form = Ui_Form()
	  	self.Ui_Form.setupUi(self)
	  	# 禁用最大化和窗口拉伸
		self.setFixedSize(self.width(),self.height())

	def closeEvent(self, event):
		reply = QMessageBox.question(self, 'Information',"Are you sure to quit?", QMessageBox.Yes|QMessageBox.No, QMessageBox.Yes)
  		if reply == QMessageBox.Yes:
   			event.accept()
		else:
			event.ignore()

	def threadFunc(self,content):#线程槽函数
		self.Ui_Form.lineEdit.setText(content)
		return

	def thread1(self):#UI按键槽函数
		self.Thread1 = MyThread(10)
  		self.Thread1.Signal1.connect(self.threadFunc)
  		self.Thread1.start()

	def thread2(self):#UI按键槽函数
		self.Thread2 = MyThread(20)
  		self.Thread2.Signal1.connect(self.threadFunc)
  		self.Thread2.start()

if __name__=="__main__":
	app = QApplication(sys.argv)
	MainWin = QmyMainWindow()
	MainWin.show()
	sys.exit(app.exec_())				
#Qt designer生成的UI TestUI.py
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Form(object): 
	def setupUi(self, Form):
		Form.setObjectName("Form")
	        Form.resize(530, 471)
	        self.lineEdit = QtWidgets.QLineEdit(Form)
	        self.lineEdit.setGeometry(QtCore.QRect(100, 180, 331, 21))
	        self.lineEdit.setObjectName("lineEdit")
	        self.Run = QtWidgets.QPushButton(Form)
	        self.Run.setGeometry(QtCore.QRect(120, 260, 93, 28))
	        self.Run.setObjectName("Run")
	        self.Stop = QtWidgets.QPushButton(Form)
	        self.Stop.setGeometry(QtCore.QRect(310, 260, 93, 28))
	        self.Stop.setObjectName("Stop")
	
		self.retranslateUi(Form)
	        self.Run.clicked.connect(Form.thread1)
	        self.Stop.clicked.connect(Form.thread2)
	        QtCore.QMetaObject.connectSlotsByName(Form)
	
	def retranslateUi(self, Form):
		_translate = QtCore.QCoreApplication.translate
        	Form.setWindowTitle(_translate("Form", "Form"))
        	self.Run.setText(_translate("Form", "Thread1"))
		self.Stop.setText(_translate("Form", "Thread2"))

效果图

执行截图

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值