Python-PyQt5-多线程测试

文章目录

  • 前言
  • 1 概念
    • 什么是线程?
    • 什么是进程?
  • 2 多线程
  • PyQt5中的线程操作
  • 总结

前言

努力是为了让你的目标更明确,但方向若错了,那可能就成了最遗憾的意外了

今天学习一下Python里的多线程的应用。但大家要清楚什么是线程,什么是进程,要区分二者概念

1 概念

什么是线程?

线程是一个轻量级的子进程,是最小的处理单元。可以说线程是进程的子集。
线程是独立的,一个线程发生错误,不影响其他线程正常执行。

什么是进程?

进程是指正在运行中的应用程序。每个进程都有自己独立的内存空间,当用户启动一个进程时,操作系统就会为该进程分配一个独立的内存空间,让应用程序在独立内存中运行

2 多线程

我们知道python是解释型语言,程序是从上向下解释一句执行一句,如果上面的程序出现的死循环,则下方的程序时不会执行的。接下来就做一个简单的测试。

import time  # 导入时间模块

def test1():
    while True:
        print("线程1")
        time.sleep(1)  # 延时1秒防止数据太快

def test2():
    while True:
        print("线程2")
        time.sleep(1)  # 延时1秒防止数据太快

if __name__ == '__main__':

    test1()
    test2()
    

Python-PyQt5-多线程测试_第1张图片
我们可以看到程序执行到test(1)时进入了死循环,所以test(2)不执行。那么如何处理这类问题呢?这里我们就要用到多进程处理。

多进程处理
这里用到了一个模块threading
首先导入这个模块

import threading  # 导入线程模块
import time  # 导入时间模块

# 定义一个线程1函数
def test1():
    while True:
        print("线程1")
        time.sleep(1)  # 延时1秒防止数据太快
        
# 定义一个线程2函数
def test2():
    while True:
        print("线程2")
        time.sleep(1)  # 延时1秒防止数据太快

if __name__ == '__main__':

    
    t1 = threading.Thread(target=test1)     # 设置为线程
    t1.start()  # 开启线程1
    t2 = threading.Thread(target=test2)    #  设置为线程
    t2.start()  # 开启线程2

执行效果
Python-PyQt5-多线程测试_第2张图片
从上面的图片我们可以看出当线程处理时,并不是线程1执行一句,线程2执行一句,而是二者随机执行,所以在相同时间内,线程1和线程2执行的次数不一样多。这个就需要我们特别注意,用多线程处理全局变量时可能会出错。

我们说过一个线程出错不会影响其他线程
现在来做一个简单测试。
Python-PyQt5-多线程测试_第3张图片
执行效果
Python-PyQt5-多线程测试_第4张图片

我们可以看到当线程1出错时,并不影响线程2的执行,所以线程互相不影响。

PyQt5中的线程操作

就拿最简单的例子来说,在一个窗口实时显示刷新当前的时间Python-PyQt5-多线程测试_第5张图片
接下来就是代码的处理

from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5 import QtCore, QtGui, QtWidgets
import time
class backendthread(QThread): #  声明一个类
        updata = pyqtSignal(str)  #  一个字符串的类的信号
        def run(self):
                while True:
                        data = time.ctime() # 获取本地时间
                        self.updata.emit(str(data))
                        time.sleep(1)  #  睡眠一秒

注意导入相关线程和信号类库。如果是用QTdesigner生成的py代码,就要在生成的代码里去写
Python-PyQt5-多线程测试_第6张图片写完信号后我们要写一个槽去用这个信号

def initUI(self):
    self.back= backendthread()
    self.back.updata.connect(self.display)  # 链接到一个display槽函数
    self.back.start()
def display(self,data):  # 编写这个槽函数
    self.text2.setText(data)  #  将时间显示出来
    

下面定义的def initUI(self):函数,注意在前面的def setupUi(self, Form):下面添加
Python-PyQt5-多线程测试_第7张图片
Python-PyQt5-多线程测试_第8张图片
最后我附上我的这个用designer生成并修改后的登录界面的py文件的所有程序,由于里面的控件多所以程序也多,大家只用看第一个函数和后面两个函数就可以了。
我没有给出我的main.py,但上几篇博客里已经给出来。由于今天没修改main.py,所以没必要给,不然代码会更多。

from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5 import QtCore, QtGui, QtWidgets
import time
class backendthread(QThread):
        updata = pyqtSignal(str)
        def run(self):
                while True:
                        data = time.ctime()
                        self.updata.emit(str(data))
                        time.sleep(1)

class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(861, 479)
        Form.setBaseSize(QtCore.QSize(0, 0))
        Form.setStyleSheet("\n"
"QWidget {\n"
"border-image:url(C:/Users/DELL/Pictures/Saved Pictures/1.jpg);\n"
"}\n"
"\n"
"QTextBrowser {\n"
"border-image:url();\n"
"}\n"
"QLineEdit {\n"
"border-image:url();\n"
"}\n"
"QComboBox {\n"
"border-image:url();\n"
"}\n"
"QLabel {\n"
"border-image:url();\n"
"}\n"
"QPushButton {\n"
"border-image:url();\n"
"}")
        self.horizontalLayout = QtWidgets.QHBoxLayout(Form)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.verticalLayout = QtWidgets.QVBoxLayout()
        self.verticalLayout.setObjectName("verticalLayout")
        spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
        self.verticalLayout.addItem(spacerItem)
        self.textBrowser = QtWidgets.QTextBrowser(Form)
        self.textBrowser.setMaximumSize(QtCore.QSize(165000, 115))
        self.textBrowser.setStyleSheet("QTextBrowser\n"
"{\n"
"background-color: rgba(255,255,255,0);\n"
"border:none;\n"
"\n"
"}")
        self.textBrowser.setObjectName("textBrowser")
        self.verticalLayout.addWidget(self.textBrowser)
        self.gridLayout = QtWidgets.QGridLayout()
        self.gridLayout.setObjectName("gridLayout")
        self.text1 = QtWidgets.QTextBrowser(Form)
        self.text1.setMaximumSize(QtCore.QSize(200, 30))
        font = QtGui.QFont()
        font.setFamily("AcadEref")
        font.setPointSize(11)
        font.setBold(True)
        font.setWeight(75)
        self.text1.setFont(font)
        self.text1.setStyleSheet("QTextBrowser\n"
"{\n"
"background-color: rgba(255,255,255,180);\n"
"border:none;\n"
"color:#55007f;\n"
"}")
        self.text1.setObjectName("text1")
        self.gridLayout.addWidget(self.text1, 1, 5, 1, 1)
        self.label_4 = QtWidgets.QLabel(Form)
        self.label_4.setMaximumSize(QtCore.QSize(140, 16777215))
        font = QtGui.QFont()
        font.setFamily("AcadEref")
        font.setPointSize(11)
        font.setBold(True)
        font.setWeight(75)
        self.label_4.setFont(font)
        self.label_4.setStyleSheet("QLabel\n"
"{\n"
"color:#ffff00;\n"
"\n"
"}")
        self.label_4.setObjectName("label_4")
        self.gridLayout.addWidget(self.label_4, 1, 3, 1, 1)
        spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.gridLayout.addItem(spacerItem1, 8, 2, 1, 1)
        self.comboBox = QtWidgets.QComboBox(Form)
        self.comboBox.setMaximumSize(QtCore.QSize(16777215, 16770000))
        self.comboBox.setObjectName("comboBox")
        self.comboBox.addItem("")
        self.comboBox.addItem("")
        self.gridLayout.addWidget(self.comboBox, 1, 2, 1, 1)
        self.lineEdit_3 = QtWidgets.QLineEdit(Form)
        self.lineEdit_3.setMinimumSize(QtCore.QSize(0, 25))
        self.lineEdit_3.setMaximumSize(QtCore.QSize(200, 40))
        self.lineEdit_3.setStyleSheet("QLineEdit\n"
"{\n"
"background-color: rgba(255,255,255,180);\n"
"border:none;\n"
"}")
        self.lineEdit_3.setObjectName("lineEdit_3")
        self.gridLayout.addWidget(self.lineEdit_3, 9, 5, 1, 1)
        spacerItem2 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
        self.gridLayout.addItem(spacerItem2, 8, 1, 1, 1)
        spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.gridLayout.addItem(spacerItem3, 1, 6, 1, 1)
        spacerItem4 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
        self.gridLayout.addItem(spacerItem4, 2, 3, 1, 1)
        spacerItem5 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
        self.gridLayout.addItem(spacerItem5, 10, 3, 1, 1)
        self.label_3 = QtWidgets.QLabel(Form)
        font = QtGui.QFont()
        font.setFamily("Adobe 宋体 Std L")
        font.setPointSize(11)
        font.setBold(True)
        font.setItalic(False)
        font.setWeight(75)
        self.label_3.setFont(font)
        self.label_3.setStyleSheet("QLabel\n"
"{color:#ffff00;\n"
"}")
        self.label_3.setObjectName("label_3")
        self.gridLayout.addWidget(self.label_3, 1, 1, 1, 1)
        self.label_2 = QtWidgets.QLabel(Form)
        font = QtGui.QFont()
        font.setFamily("新宋体")
        font.setPointSize(11)
        font.setBold(True)
        font.setWeight(75)
        self.label_2.setFont(font)
        self.label_2.setStyleSheet("QLabel\n"
"{\n"
"color:#ffff00;\n"
"\n"
"}")
        self.label_2.setObjectName("label_2")
        self.gridLayout.addWidget(self.label_2, 9, 1, 1, 1)
        self.label_5 = QtWidgets.QLabel(Form)
        font = QtGui.QFont()
        font.setFamily("AcadEref")
        font.setPointSize(11)
        font.setBold(True)
        font.setWeight(75)
        self.label_5.setFont(font)
        self.label_5.setStyleSheet("QLabel\n"
"{\n"
"color:#ffff00;\n"
"\n"
"}")
        self.label_5.setObjectName("label_5")
        self.gridLayout.addWidget(self.label_5, 7, 3, 1, 1)
        self.lineEdit = QtWidgets.QLineEdit(Form)
        self.lineEdit.setMaximumSize(QtCore.QSize(117, 25))
        self.lineEdit.setStyleSheet("QLineEdit\n"
"{\n"
"background-color: rgba(255,255,255,180);\n"
"border:none;\n"
"}")
        self.lineEdit.setObjectName("lineEdit")
        self.gridLayout.addWidget(self.lineEdit, 7, 2, 1, 1)
        self.label = QtWidgets.QLabel(Form)
        self.label.setMaximumSize(QtCore.QSize(150, 16777215))
        font = QtGui.QFont()
        font.setFamily("AcadEref")
        font.setPointSize(11)
        font.setBold(True)
        font.setWeight(75)
        self.label.setFont(font)
        self.label.setStyleSheet("QLabel\n"
"{\n"
"color:#ffff00;\n"
"\n"
"}")
        self.label.setObjectName("label")
        self.gridLayout.addWidget(self.label, 7, 1, 1, 1)
        self.pushButton_2 = QtWidgets.QPushButton(Form)
        self.pushButton_2.setEnabled(False)
        self.pushButton_2.setStyleSheet("QPushButton\n"
"{\n"
"background-color:blue;\n"
"color:#ffffff;\n"
"font: 75 13pt \"新宋体\";\n"
"}")
        self.pushButton_2.setObjectName("pushButton_2")
        self.gridLayout.addWidget(self.pushButton_2, 11, 2, 1, 1)
        self.text2 = QtWidgets.QTextBrowser(Form)
        self.text2.setMaximumSize(QtCore.QSize(200, 30))
        font = QtGui.QFont()
        font.setFamily("新宋体")
        font.setPointSize(8)
        font.setBold(False)
        font.setWeight(50)
        self.text2.setFont(font)
        self.text2.viewport().setProperty("cursor", QtGui.QCursor(QtCore.Qt.IBeamCursor))
        self.text2.setAutoFillBackground(True)
        self.text2.setStyleSheet("QTextBrowser\n"
"{\n"
"background-color: rgba(255,255,255,0);\n"
"border:none;\n"
"color:#00ff00;\n"
"}")
        self.text2.setLineWidth(2)
        self.text2.setReadOnly(True)
        self.text2.setOverwriteMode(False)
        self.text2.setSearchPaths([])
        self.text2.setOpenLinks(True)
        self.text2.setObjectName("text2")
        self.gridLayout.addWidget(self.text2, 7, 5, 1, 1)
        self.lineEdit_4 = QtWidgets.QLineEdit(Form)
        self.lineEdit_4.setMinimumSize(QtCore.QSize(0, 25))
        self.lineEdit_4.setMaximumSize(QtCore.QSize(200, 16777215))
        self.lineEdit_4.setAutoFillBackground(False)
        self.lineEdit_4.setStyleSheet("QLineEdit\n"
"{\n"
"background-color: rgba(255,255,255,180);\n"
"border:none;\n"
"}")
        self.lineEdit_4.setObjectName("lineEdit_4")
        self.gridLayout.addWidget(self.lineEdit_4, 11, 5, 1, 1)
        self.label_6 = QtWidgets.QLabel(Form)
        font = QtGui.QFont()
        font.setFamily("AcadEref")
        font.setPointSize(11)
        font.setBold(True)
        font.setWeight(75)
        self.label_6.setFont(font)
        self.label_6.setStyleSheet("QLabel\n"
"{\n"
"color:#ffff00;\n"
"\n"
"}")
        self.label_6.setObjectName("label_6")
        self.gridLayout.addWidget(self.label_6, 11, 3, 1, 1)
        self.label_7 = QtWidgets.QLabel(Form)
        font = QtGui.QFont()
        font.setFamily("AcadEref")
        font.setPointSize(11)
        font.setBold(True)
        font.setWeight(75)
        self.label_7.setFont(font)
        self.label_7.setStyleSheet("QLabel\n"
"{\n"
"color:#ffff00;\n"
"\n"
"}")
        self.label_7.setObjectName("label_7")
        self.gridLayout.addWidget(self.label_7, 9, 3, 1, 1)
        self.lineEdit_2 = QtWidgets.QLineEdit(Form)
        self.lineEdit_2.setMaximumSize(QtCore.QSize(117, 25))
        self.lineEdit_2.setAutoFillBackground(False)
        self.lineEdit_2.setStyleSheet("QLineEdit\n"
"{\n"
"background-color: rgba(255,255,255,180);\n"
"border:none;\n"
"}")
        self.lineEdit_2.setText("")
        self.lineEdit_2.setObjectName("lineEdit_2")
        self.gridLayout.addWidget(self.lineEdit_2, 9, 2, 1, 1)
        spacerItem6 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.gridLayout.addItem(spacerItem6, 2, 1, 1, 1)
        self.pushButton = QtWidgets.QPushButton(Form)
        self.pushButton.setEnabled(True)
        self.pushButton.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
        self.pushButton.setStyleSheet("QPushButton\n"
"{\n"
"background-color:blue;\n"
"color:#ffffff;\n"
"font: 75 13pt \"新宋体\";\n"
"}")
        self.pushButton.setObjectName("pushButton")
        self.gridLayout.addWidget(self.pushButton, 11, 1, 1, 1)
        spacerItem7 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
        self.gridLayout.addItem(spacerItem7, 11, 0, 1, 1)
        self.text3 = QtWidgets.QTextBrowser(Form)
        self.text3.setMaximumSize(QtCore.QSize(200, 30))
        self.text3.setStyleSheet("QTextBrowser\n"
"{\n"
"background-color: rgba(255,255,255,0);\n"
"border:none;\n"
"color:#ffff00;\n"
"\n"
"}\n"
"")
        self.text3.setObjectName("text3")
        self.gridLayout.addWidget(self.text3, 8, 5, 1, 1)
        self.verticalLayout.addLayout(self.gridLayout)
        spacerItem8 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
        self.verticalLayout.addItem(spacerItem8)
        self.horizontalLayout.addLayout(self.verticalLayout)
        self.initUI()
        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)
    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "系统登录"))
        self.textBrowser.setHtml(_translate("Form", "\n"
"\n"
"

基于活体检测的PCA多特征人脸识别门禁考勤管理系统

"
)) self.text1.setHtml(_translate("Form", "\n" "\n" "


"
)) self.label_4.setText(_translate("Form", " 登录状态显示:")) self.comboBox.setItemText(0, _translate("Form", "管理员")) self.comboBox.setItemText(1, _translate("Form", "普通用户")) self.label_3.setText(_translate("Form", " 权限选择:")) self.label_2.setText(_translate("Form", " 密 码:")) self.label_5.setText(_translate("Form", " 时间:")) self.label.setText(_translate("Form", " 用户名:")) self.pushButton_2.setText(_translate("Form", "注册")) self.text2.setHtml(_translate("Form", "\n" "\n" "


"
)) self.label_6.setText(_translate("Form", " 超级权限:")) self.label_7.setText(_translate("Form", " 验证码:")) self.pushButton.setText(_translate("Form", "登陆")) self.text3.setHtml(_translate("Form", "\n" "\n" "

4+8=

"
)) def initUI(self): self.back= backendthread() self.back.updata.connect(self.display) self.back.start() def display(self,data): self.text2.setText(data)

到这就全部编写完成,我们来运行一下看看效果,时间确实是显示出来了。但原谅我没gif图。
Python-PyQt5-多线程测试_第9张图片
Python-PyQt5-多线程测试_第10张图片

总结

其实PyQt5里的用多线程刷新UI界面还是不太好写的,我也是早上查了好多资料才实现的,像类似这种问题b站也有一些教程。我这篇可能偏实际开发,因为我就是在我现在正在做的项目上直接去做的,代码有点多,不适合新手去看,因为新手可能看不懂,不知道这么多代码什么地方该看什么地方是重点,什么地方可以直接跳过不看。
建议
总之一句话,想学好多线程,就要多看,多查,多尝试。这篇博文只是针对开发时解决的一个时间实时显示的功能。一个案例并不能学懂线程,一定要多看一些实战案例。这样才能有更深一步的了解。

:我也并不是专业开发python的,只是一个python的爱好者。

你可能感兴趣的:(python学习)