• PyQt5学习笔记--多线程处理、数据交互


    目录

    1--引入多线程的原因

    2--PyQt多线程的基本知识

    3--多线程登录程序的实例

    4--参考


    1--引入多线程的原因

    ① 如果Qt只采用单线程任务的方式,当遇到数据处理慢的情形时,会出现GUI卡死的情况。

    ② 使用下述例子展示单线程任务的缺陷:

    ③ 代码:

    1. import sys
    2. import time
    3. from PyQt5 import uic
    4. from PyQt5.QtCore import QThread
    5. from PyQt5.QtWidgets import QWidget, QApplication
    6. class MyThread(QThread):
    7. def __init__(self):
    8. super().__init__()
    9. def run(self):
    10. for i in range(10):
    11. print("是MyThread线程中执行....%d" % (i + 1))
    12. time.sleep(1)
    13. class MyWin(QWidget):
    14. def __init__(self):
    15. super().__init__()
    16. self.init_ui()
    17. def init_ui(self):
    18. self.ui = uic.loadUi("./thread.ui")
    19. # 从ui文件中加载控件
    20. line_edit = self.ui.lineEdit
    21. btn1 = self.ui.pushButton
    22. btn2 = self.ui.pushButton_2
    23. # 控件绑定槽函数
    24. btn1.clicked.connect(self.click_1)
    25. btn2.clicked.connect(self.click_2)
    26. def click_1(self):
    27. for i in range(10):
    28. print("是UI线程中执行....%d" % (i + 1))
    29. time.sleep(1)
    30. def click_2(self):
    31. self.my_thread = MyThread() # 创建线程
    32. self.my_thread.start() # 开始线程
    33. if __name__ == "__main__":
    34. app = QApplication(sys.argv)
    35. myshow = MyWin()
    36. myshow.ui.show()
    37. sys.exit(app.exec_())

    ④ 结果展示:

    当点击第一个button时,GUI会出现卡顿无法显示输出的问题;当点击第二个button时,GUI可以正常工作,输入框可以正常显示输入的内容。

    2--PyQt多线程的基本知识

    ① 通过继承父类QThread可以新建子线程;

    ② 线程之间可以通过信号进行交互,并通过其槽函数执行对应的功能;

    ③ 常用函数:(后面会专门写一篇笔记,其内容是如何在线程之间通过信号传递opencv图片、numpy数组等数据格式)

    1. signal = pyqtSignal(str); # 创建信号
    2. signal.emit(json); # 发送信号
    3. json = json.dumps(data); # 将数据序列化封装
    4. data = json.loads(json); # 将数据还原

    3--多线程登录程序的实例

    ① 基于Qt Designer设计 ui 文件:

     ② 代码:

    1. import json
    2. import sys
    3. import time
    4. from PyQt5.QtCore import *
    5. from PyQt5.QtWidgets import *
    6. from PyQt5 import uic
    7. # 子线程
    8. class LoginThread(QThread):
    9. # 创建信号 接受字符串(这里用于主线程向子线程传递信息)
    10. start_login_signal = pyqtSignal(str)
    11. def __init__(self, signal):
    12. super().__init__()
    13. # 信号绑定槽函数
    14. self.start_login_signal.connect(self.login_by_requests)
    15. self.login_complete_signal = signal
    16. def login_by_requests(self, user_password_json):
    17. # 将json字符串转换
    18. user_password_dict = json.loads(user_password_json)
    19. user_name = user_password_dict.get("user_name")
    20. password = user_password_dict.get("password")
    21. print(user_name, password)
    22. # 比对登录信息,返回登录状态(可自由扩充)
    23. if user_name == "liujinfu" and password == "liujinfu":
    24. self.login_complete_signal.emit(json.dumps(True)) # 返回True
    25. else:
    26. self.login_complete_signal.emit(json.dumps(False)) # 返回False
    27. def run(self):
    28. while True: # 让子线程一直运行,等待主线程(ui线程)下发的任务
    29. print("子线程正在等待执行....")
    30. time.sleep(2)
    31. # 主线程
    32. class MyWindow(QWidget):
    33. # 创建信号(这里用于子线程向主线程返回信息)
    34. login_status_signal = pyqtSignal(str)
    35. def __init__(self):
    36. super().__init__()
    37. self.init_ui()
    38. def init_ui(self):
    39. self.ui = uic.loadUi("./login.ui") # 加载由Qt Designer设计的ui文件
    40. self.user_name_qwidget = self.ui.lineEdit # 用户名输入框
    41. self.password_qwidget = self.ui.lineEdit_2 # 密码输入框
    42. self.login_btn = self.ui.pushButton # 登录按钮
    43. self.forget_btn = self.ui.pushButton_2 # 忘记密码按钮
    44. self.text_browser = self.ui.textBrowser # 文本显示区域
    45. # 绑定槽函数
    46. self.login_btn.clicked.connect(self.login)
    47. self.login_thread = LoginThread(self.login_status_signal) # 登录子线程
    48. self.login_thread.start() # 让子线程开始工作
    49. self.login_status_signal.connect(self.login_status)
    50. def login(self):
    51. # 实现登录函数
    52. self.user_name = self.user_name_qwidget.text()
    53. self.password = self.password_qwidget.text()
    54. # 发送信号,让子线程开始登录
    55. self.login_thread.start_login_signal.emit(json.dumps({"user_name": self.user_name, "password": self.password}))
    56. def login_status(self, status):
    57. # 根据登录状态打印信息(可自由扩充)
    58. if json.loads(status):
    59. self.text_browser.setText("Welcome %s !" % self.user_name)
    60. self.text_browser.repaint()
    61. else:
    62. self.text_browser.setText("User_name or password is not correct, please try again !")
    63. self.text_browser.repaint()
    64. if __name__ == '__main__':
    65. app = QApplication(sys.argv) # 创建对象
    66. w = MyWindow()
    67. # 展示窗口
    68. w.ui.show()
    69. # 程序进行循环等待状态
    70. app.exec_()

    ③ 结果展示:

    注:后面会专门写一篇笔记,其内容是如何在线程之间通过信号传递opencv图片、numpy数组等数据格式

    4--参考

    PyQt5 快速入门

  • 相关阅读:
    as设置java home
    go语言 Error 1040: Too many connections 最大连接数
    【小程序源码】全新优化版趣味语句生成器
    2022年度GitHub中文Java项目排行榜Top 10
    计算机网络(三):数据链路层
    virustotal-请求头参数逆向
    Arm机密计算架构技术(Armv9 CCA) 白皮书
    Responder
    RabbitMQ 系列教程
    Vue----组件
  • 原文地址:https://blog.csdn.net/weixin_43863869/article/details/128060012