当前位置:   article > 正文

PyQt上手教程汇总_pyqt教程

pyqt教程

根据此前的PyQt学习,这里对PyQt的学习过程进行最后的总结

前文链接:由于前文标题名字取了一样的,以下内容按照前后顺序排列

(1)PyQt上手教程(一)_机械刘怀洋的博客-CSDN博客

(2)PyQt上手教程(一)_机械刘怀洋的博客-CSDN博客 

(3)PyQt上手教程(一)_机械刘怀洋的博客-CSDN博客

(4)PyQt上手教程(一)_机械刘怀洋的博客-CSDN博客

(5)PyQt上手教程(一)_机械刘怀洋的博客-CSDN博客

下面是最后一点内容

(十二)腾讯云函数

后续案例要用到腾讯云函数,这里先了解一下

注册腾讯云后新建一个函数

测试函数默认先不用管

完成

创建一个触发器

创建后这里有个链接

直接访问链接,可以看到已经调用

腾讯云给人使用的免费额度是100万次

(十三)Qt Designer

利用Qt Designer可以快速设计UI界面,比起直接写代码,效率要快速很多,下面记录一下Qt Designer使用过程

(1)Python调用ui文件显示界面

由于在Pycharm中直接配置了了PyQt5,PyQt5是自带Qt Designer工具的

所以直接在Anaconda工具包中搜索designer.exe,然后发送快捷方式到桌面

Qt Designer的快捷方式如下

双击designer.exe打开设计页面,新建空白页面

拖一些控件先做一个测试页面

直接crtl+s保存为ui文件

然后利用Python调用ui文件,Python代码以及显示功能如下

(2)案例展示

为了更好理解上述过程,这里做了一个案例巩固知识

如下图先做一个页面

这里把页面右下角的信号与槽拖出来

假设设计如下的信号与槽接收页面

当点击登录的时候,文本框就会关闭,预览效果如下,但是在设计页面设计信号与槽,功能很受限

(3)控件添加信号与槽

1.这里直接使用上面案例的界面,整体代码如下

  1. """
  2. 动态加载ui文件
  3. """
  4. import sys
  5. from PyQt5.QtWidgets import *
  6. from PyQt5 import uic
  7. class MyWindow(QWidget):
  8. def __init__(self):
  9. super().__init__()
  10. self.ui = None
  11. self.user_name = None
  12. self.password = None
  13. self.init_ui()
  14. def init_ui(self):
  15. self.ui = uic.loadUi("D:\\Qt\\QtData\\PyQt\\PyQtLesson\\Qt Designer\\login_test.ui")
  16. # print(self.ui) # ui文件中最顶层的对象
  17. # print(self.ui.__dict__) # 最顶层对象的所有属性(key:value方式显示)
  18. # print(self.ui.label) # 最顶层对象中嵌套的QLabel
  19. # print(self.ui.label.text()) # 最顶层对象中嵌套的QLabel的文本
  20. self.user_name = self.ui.lineEdit # 用户名输入框
  21. self.password = self.ui.lineEdit_2 # 密码输入框
  22. login_btn = self.ui.pushButton # 登录按钮
  23. forget_btn = self.ui.pushButton_2 # 忘记密码按钮
  24. text_browser = self.ui.textBrowser # 文本显示区域
  25. # 给登录按钮被点击绑定槽函数
  26. login_btn.clicked.connect(self.login)
  27. def login(self):
  28. """实现登录的逻辑"""
  29. print("正在登录。。。。。。")
  30. # 提取用户名,密码
  31. print(self.user_name.text())
  32. print(self.password.text())
  33. if __name__ == '__main__':
  34. app = QApplication(sys.argv)
  35. w = MyWindow()
  36. w.ui.show()
  37. app.exec_()

2.关键代码分析

<1>__init__函数中声明属性

假设这里把__init__函数中的self.user_name = None等注释,Pycharm解释器会提醒

Instance attribute user_name defined outside __init__

这里的意思就是说,我在def init_ui(self):这个函数中,要给self指向的对象添加user_name这个属性,但是我在__init__函数中又没有进行这个属性的声明,于是要在__init__函数中声明一下

<2>窗口显示代码

这里我们发现窗口显示代码并不是w.show()

这是因为我们最终要显示的界面是ui所用的绘图界面,而不是调用w这个空壳界面

<3>print(self.ui.__dict__)

看看.ui文件有什么属性,如下图蓝色框,红色框是获取登录信息

在这里,我们看到加载后的.ui文件有7个对象属性,正好与在设计.ui文件时控件的数量一致,可见属性的个数正好对应.ui文件中的空间个数,所以想要操作哪个空间,就通过对象.属性的方式从.ui对象中提取即可。当然了不能盲目的提取,这些属性的名字其实就是在.ui文件中的空间的Object name,如下图

(4)点击登录按钮后槽函数的完善

这里完善一下上述的案例

  1. """
  2. 动态加载ui文件
  3. """
  4. import sys
  5. from PyQt5.QtWidgets import *
  6. from PyQt5 import uic
  7. class MyWindow(QWidget):
  8. def __init__(self):
  9. super().__init__()
  10. self.ui = None
  11. self.user_name = None
  12. self.password_qwidget = None
  13. self.login_btn = None
  14. self.forget_btn = None
  15. self.text_browser = None
  16. self.init_ui()
  17. def init_ui(self):
  18. self.ui = uic.loadUi("D:\\Qt\\QtData\\PyQt\\PyQtLesson\\Qt Designer\\login_test.ui")
  19. # 提取要操作的控件
  20. self.user_name = self.ui.lineEdit # 用户名输入框
  21. self.password_qwidget = self.ui.lineEdit_2 # 密码输入框
  22. self.login_btn = self.ui.pushButton # 登录按钮
  23. self.forget_btn = self.ui.pushButton_2 # 忘记密码按钮
  24. self.text_browser = self.ui.textBrowser # 文本显示区域
  25. # 给登录按钮被点击绑定槽函数
  26. self.login_btn.clicked.connect(self.login)
  27. def login(self):
  28. """登录按钮的槽函数"""
  29. user_name = self.user_name.text()
  30. password = self.password_qwidget.text()
  31. if user_name == "admin" and password == "123456":
  32. self.text_browser.setText("欢迎%s" % user_name)
  33. self.text_browser.repaint()
  34. else:
  35. self.text_browser.setText("用户名或密码错误...请重试")
  36. self.text_browser.repaint()
  37. if __name__ == '__main__':
  38. app = QApplication(sys.argv)
  39. w = MyWindow()
  40. w.ui.show()
  41. app.exec_()

这里增加了一个条件判断登录逻辑

展示过程如下

(5)PyQt引入多线程

<1>引入:结合(4)中的案例,加入三行代码

重新运行效果如下

运行过程中,可以很明显的看到,程序是卡顿的

原因如下:

只要是带界面的程序,一般来说程序运行后会用当前线程进行事件的检查、按钮等图形界面的更新操作,如果在执行某个逻辑代码(例如登录)时耗时非常验证,此时就会出现界面卡顿

解决办法如下:

我们一般将界面的显示用主线程来操作,逻辑功能代码或者耗时操作的代码都用另外线程进行处理

这也就是为什么要研究PyQt中的多线程了,因为它能实现多任务,让界面用一个线程更新,让逻辑代码在另外一个线程中,互不影响

<2>PyQt使用多线程

1.使用QT Designer设计如下效果ui文件

2.整体代码如下

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

3.运行如下

可以看到,单线程的时候,是无法做到同时输入的

只有在线程执行结束后,输入的内容才会显示出来

而多线程情况下,可以同时输入内容

4.关键代码分析

这里的创建线程加self的原因分析

如下图所示,虽然代码中没有调用del,但是def click_2(self):结束后会直接删掉my_thread

这时候引用技术编程0但是线程还活着,程序就不会正常运行

(6)PyQt多线程案例

这里提供了一个案例巩固上述多线程的知识点

该代码和上述代码基本相同,这里不多做介绍

<1>整体代码

  1. import json
  2. import sys
  3. import time
  4. from PyQt5 import uic
  5. from PyQt5.Qt import QApplication, QWidget, QThread
  6. from PyQt5.QtCore import pyqtSignal
  7. class LoginThread(QThread):
  8. # 创建自定义信号
  9. start_login_signal = pyqtSignal(str)
  10. def __init__(self):
  11. super().__init__()
  12. def login_by_requests(self, user_password_json):
  13. # 将json字符串,转换为自定,从而实现传递了用户名以及密码
  14. user_password_json = json.loads(user_password_json)
  15. print(user_password_json.get("user_name"))
  16. print(user_password_json.get("password"))
  17. def run(self):
  18. # 通过whileTrue的方式让子线程一直运行,而不是结束
  19. # 通过这种方式,我们让子线程一直活着,从而有能力接收来自主线程 (UI线程)的任务
  20. while True:
  21. print("子线程正在执行....")
  22. time.sleep(1)
  23. class MyWindow(QWidget):
  24. def __init__(self):
  25. super().__init__()
  26. self.ui = None
  27. self.user_name_qwidget = None
  28. self.password_qwidget = None
  29. self.login_btn = None
  30. self.forget_password_btn = None
  31. self.textBrowser = None
  32. self.login_thread = None
  33. self.init_ui()
  34. def init_ui(self):
  35. self.ui = uic.loadUi("D:\\Qt\\QtData\\PyQt\\PyQtLesson\\Qt Designer\\login_test.ui")
  36. # 提取要操作的控件
  37. self.user_name_qwidget = self.ui.lineEdit # 用户名输入框
  38. self.password_qwidget = self.ui.lineEdit_2 # 密码输入框
  39. self.login_btn = self.ui.pushButton # 登录按钮
  40. self.forget_password_btn = self.ui.pushButton_2 # 忘记密码按钮
  41. self.textBrowser = self.ui.textBrowser # 文本显示区域
  42. # 绑定信号与槽函数
  43. self.login_btn.clicked.connect(self.login)
  44. # 创建一个子线程(注意这里要将Login_thread变量变为对象的属性,如果不是对象属性,而是一个普通的局部变量的话
  45. # 会随着init_ui函数执行结束而被释放此时子线程还没有执行完毕所有会产生问题)
  46. self.login_thread = LoginThread()
  47. # 将要创建的子线程类中的信号进行绑定
  48. self.login_thread.start_login_signal.connect(self.login_thread.login_by_requests)
  49. # 让子线程开始巩工作
  50. self.login_thread.start()
  51. def login(self):
  52. """登录按钮的槽函数"""
  53. user_name = self.user_name_qwidget.text()
  54. password = self.password_qwidget.text()
  55. # 发送信号,让子线程开始登录
  56. self.login_thread.start_login_signal.emit(json.dumps({"user_name": user_name, "password": password}))
  57. if __name__ == '__main__':
  58. app = QApplication(sys.argv)
  59. w = MyWindow()
  60. w.ui.show()
  61. app.exec_()

<2>代码运行结果

(7)PyQt链接云函数

<1> 云函数的修改

在(十二)节中,已经介绍了云函数

为了在本小节介绍PyQt链接云函数,这里对之前的云函数做一下修改如下

<2> 本地整体代码

  1. import json
  2. import sys
  3. import time
  4. import requests
  5. from PyQt5 import uic
  6. from PyQt5.Qt import QApplication, QWidget, QThread
  7. from PyQt5.QtCore import pyqtSignal
  8. class LoginThread(QThread):
  9. # 创建自定义信号
  10. start_login_signal = pyqtSignal(str)
  11. def __init__(self, signal):
  12. super().__init__()
  13. self.login_complete_signal = signal
  14. def login_by_requests(self, user_password_json):
  15. # 将json字符串,转换为自定,从而实现传递了用户名以及密码
  16. user_password_json = json.loads(user_password_json)
  17. print(user_password_json.get("user_name"))
  18. print(user_password_json.get("password"))
  19. # 使用requests模块发送请求(POST)
  20. r = requests.post(url = "https://service-ed6mmhrc-1318499709.nj.apigw.tencentcs.com/release/test"
  21. , json = user_password_json())
  22. print("收到腾讯服务器的相应:", r.content.decode())
  23. ret = r.json()
  24. print("这里要发送信号给UI线程.....")
  25. self.login_complete_signal.emit(json.dumps(ret))
  26. def run(self):
  27. # 通过whileTrue的方式让子线程一直运行,而不是结束
  28. # 通过这种方式,我们让子线程一直活着,从而有能力接收来自主线程 (UI线程)的任务
  29. while True:
  30. print("子线程正在执行....")
  31. time.sleep(1)
  32. class MyWindow(QWidget):
  33. # 创建定义信号
  34. login_status_signal = pyqtSignal(str)
  35. def __init__(self):
  36. super().__init__()
  37. self.ui = None
  38. self.user_name_qwidget = None
  39. self.password_qwidget = None
  40. self.login_btn = None
  41. self.forget_password_btn = None
  42. self.textBrowser = None
  43. self.login_thread = None
  44. self.init_ui()
  45. def init_ui(self):
  46. self.ui = uic.loadUi("D:\\Qt\\QtData\\PyQt\\PyQtLesson\\Qt Designer\\login_test.ui")
  47. # 提取要操作的控件
  48. self.user_name_qwidget = self.ui.lineEdit # 用户名输入框
  49. self.password_qwidget = self.ui.lineEdit_2 # 密码输入框
  50. self.login_btn = self.ui.pushButton # 登录按钮
  51. self.forget_password_btn = self.ui.pushButton_2 # 忘记密码按钮
  52. self.textBrowser = self.ui.textBrowser # 文本显示区域
  53. # 绑定信号与槽函数
  54. self.login_btn.clicked.connect(self.login)
  55. # 创建一个信号,用让子线程登录成功之后向主线程发送
  56. self.login_status_signal.connect(self.login_status)
  57. # 创建一个子线程(注意这里要将Login_thread变量变为对象的属性,如果不是对象属性,而是一个普通的局部变量的话
  58. # 会随着init_ui函数执行结束而被释放此时子线程还没有执行完毕所有会产生问题)
  59. self.login_thread = LoginThread(self.login_status_signal)
  60. # 将要创建的子线程类中的信号进行绑定
  61. self.login_thread.start_login_signal.connect(self.login_thread.login_by_requests)
  62. # 让子线程开始巩工作
  63. self.login_thread.start()
  64. def login(self):
  65. """登录按钮的槽函数"""
  66. user_name = self.user_name_qwidget.text()
  67. password = self.password_qwidget.text()
  68. # 发送信号,让子线程开始登录
  69. self.login_thread.start_login_signal.emit(json.dumps({"user_name": user_name, "password": password}))
  70. def login_status(self, status):
  71. print("status.....", status)
  72. status_dict = json.loads(status)
  73. self.textBrowser.setText(status_dict.get("errmsg"))
  74. self.textBrowser.repaint()
  75. if __name__ == '__main__':
  76. app = QApplication(sys.argv)
  77. w = MyWindow()
  78. w.ui.show()
  79. app.exec_()

<3> 重要代码解析

本段代码中最重要的是使用requests模块向网站发送请求

<4> 运行结果

可以从运行结果中看出来,已经 收到了腾讯服务器的相应病输出了登录的信息

 由于电脑的性能不够,在运行代码的时候报了如下提示,经过查询是正常的

 到此,PyQt的基础上手教程到此完整的过了一遍

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/700942
推荐阅读
相关标签
  

闽ICP备14008679号