Multithreading of pyqt5 taking notes

@ pyqt5
When running a program with multi-threaded pyqt5, if the program takes too long, the interface will freeze. The solution can be to put the program that takes too long into the thread.

One, rewrite the QThread class

#需要加载模块中的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. Custom trigger signal

The pyqtSignal() custom trigger signal is a class variable, and the parameter type can be str, int, None, list and other forms to indicate the signal type of the trigger.

2,run()

Override the run() method in a custom thread class. The thread function written in the run() method is generally a function that takes a long time or is executed repeatedly.

3,emit()

emit() is used to trigger the slot function. The parameter type is the same as the parameter type of pyqtSignal(), indicating the type of trigger signal. The parameters of emit() will be passed to the slot function connected to this signal.

4. On the importance of time delay

When I first looked at other people's introductions, I didn't understand why I had to add a delay at the end. I didn't understand the importance of delay until my program was executed and the interface suspended animation after adding multiple threads.
If the thread function triggers the slot function as a loop trigger, and the running time in each loop is too short, the thread frequently triggers the slot function and the interval of accessing the main interface is too short, it will appear that the main interface runs all the time and the interface freezes.

Second, thread execution

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

1. First, instantiate, create a thread instance, and initialize it.
2. When the thread executes, it still follows the signal and slot function mechanism of qt. By rewriting the custom trigger signal in the Qthread class, the thread triggers the Signal1 signal and connects to the slot function threadFunc. The slot function interacts with the interface, that is, the function is separated from the UI , The execution function part in the run() function, and the interface interaction in the slot function. Thread and slot function passing parameters are passed through the emit() trigger function.
3. When start() is executed, the thread starts to execute, and the run() function in the thread class will be executed automatically.

Three, timing

The main thread executes, executes to the start() of the child thread, the main thread continues to execute, and the child thread automatically jumps to the run() function to perform the function of the child thread. Until emit() triggers the signal to the threadFun slot function, interacts with the UI, and returns to the main thread. At this time, if the execution of the main thread code segment is completed, the slot function is executed. The main thread code segment has not been executed, and the slot function is executed after the main thread code segment is executed.

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

Four, code examples

Post a code record you wrote casually

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"))

Effect picture

Execute screenshot

Guess you like

Origin blog.csdn.net/Lhhxxdhr/article/details/106719649