目录
1--引入多线程的原因
2--PyQt多线程的基本知识
3--多线程登录程序的实例
4--参考
1--引入多线程的原因
① 如果Qt只采用单线程任务的方式,当遇到数据处理慢的情形时,会出现GUI卡死的情况。
② 使用下述例子展示单线程任务的缺陷:
③ 代码:
import sys
import time
from PyQt5 import uic
from PyQt5.QtCore import QThread
from PyQt5.QtWidgets import QWidget, QApplication
class MyThread(QThread):
def __init__(self):
super().__init__()
def run(self):
for i in range(10):
print("是MyThread线程中执行....%d" % (i + 1))
time.sleep(1)
class MyWin(QWidget):
def __init__(self):
super().__init__()
self.init_ui()
def init_ui(self):
self.ui = uic.loadUi("./thread.ui")
# 从ui文件中加载控件
line_edit = self.ui.lineEdit
btn1 = self.ui.pushButton
btn2 = self.ui.pushButton_2
# 控件绑定槽函数
btn1.clicked.connect(self.click_1)
btn2.clicked.connect(self.click_2)
def click_1(self):
for i in range(10):
print("是UI线程中执行....%d" % (i + 1))
time.sleep(1)
def click_2(self):
self.my_thread = MyThread() # 创建线程
self.my_thread.start() # 开始线程
if __name__ == "__main__":
app = QApplication(sys.argv)
myshow = MyWin()
myshow.ui.show()
sys.exit(app.exec_())
④ 结果展示:
当点击第一个button时,GUI会出现卡顿无法显示输出的问题;当点击第二个button时,GUI可以正常工作,输入框可以正常显示输入的内容。
2--PyQt多线程的基本知识
① 通过继承父类QThread可以新建子线程;
② 线程之间可以通过信号进行交互,并通过其槽函数执行对应的功能;
③ 常用函数:(后面会专门写一篇笔记,其内容是如何在线程之间通过信号传递opencv图片、numpy数组等数据格式)
signal = pyqtSignal(str); # 创建信号
signal.emit(json); # 发送信号
json = json.dumps(data); # 将数据序列化封装
data = json.loads(json); # 将数据还原
3--多线程登录程序的实例
① 基于Qt Designer设计 ui 文件:
② 代码:
import json
import sys
import time
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5 import uic
# 子线程
class LoginThread(QThread):
# 创建信号 接受字符串(这里用于主线程向子线程传递信息)
start_login_signal = pyqtSignal(str)
def __init__(self, signal):
super().__init__()
# 信号绑定槽函数
self.start_login_signal.connect(self.login_by_requests)
self.login_complete_signal = signal
def login_by_requests(self, user_password_json):
# 将json字符串转换
user_password_dict = json.loads(user_password_json)
user_name = user_password_dict.get("user_name")
password = user_password_dict.get("password")
print(user_name, password)
# 比对登录信息,返回登录状态(可自由扩充)
if user_name == "liujinfu" and password == "liujinfu":
self.login_complete_signal.emit(json.dumps(True)) # 返回True
else:
self.login_complete_signal.emit(json.dumps(False)) # 返回False
def run(self):
while True: # 让子线程一直运行,等待主线程(ui线程)下发的任务
print("子线程正在等待执行....")
time.sleep(2)
# 主线程
class MyWindow(QWidget):
# 创建信号(这里用于子线程向主线程返回信息)
login_status_signal = pyqtSignal(str)
def __init__(self):
super().__init__()
self.init_ui()
def init_ui(self):
self.ui = uic.loadUi("./login.ui") # 加载由Qt Designer设计的ui文件
self.user_name_qwidget = self.ui.lineEdit # 用户名输入框
self.password_qwidget = self.ui.lineEdit_2 # 密码输入框
self.login_btn = self.ui.pushButton # 登录按钮
self.forget_btn = self.ui.pushButton_2 # 忘记密码按钮
self.text_browser = self.ui.textBrowser # 文本显示区域
# 绑定槽函数
self.login_btn.clicked.connect(self.login)
self.login_thread = LoginThread(self.login_status_signal) # 登录子线程
self.login_thread.start() # 让子线程开始工作
self.login_status_signal.connect(self.login_status)
def login(self):
# 实现登录函数
self.user_name = self.user_name_qwidget.text()
self.password = self.password_qwidget.text()
# 发送信号,让子线程开始登录
self.login_thread.start_login_signal.emit(json.dumps({"user_name": self.user_name, "password": self.password}))
def login_status(self, status):
# 根据登录状态打印信息(可自由扩充)
if json.loads(status):
self.text_browser.setText("Welcome %s !" % self.user_name)
self.text_browser.repaint()
else:
self.text_browser.setText("User_name or password is not correct, please try again !")
self.text_browser.repaint()
if __name__ == '__main__':
app = QApplication(sys.argv) # 创建对象
w = MyWindow()
# 展示窗口
w.ui.show()
# 程序进行循环等待状态
app.exec_()
③ 结果展示:
注:后面会专门写一篇笔记,其内容是如何在线程之间通过信号传递opencv图片、numpy数组等数据格式文章来源:https://www.toymoban.com/news/detail-415527.html
4--参考
PyQt5 快速入门文章来源地址https://www.toymoban.com/news/detail-415527.html
到了这里,关于PyQt5学习笔记--多线程处理、数据交互的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!