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.这里直接使用上面案例的界面,整体代码如下

"""
动态加载ui文件
"""
import sys
from PyQt5.QtWidgets import *
from PyQt5 import uic

class MyWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.ui = None
        self.user_name = None
        self.password = None
        self.init_ui()

    def init_ui(self):
        self.ui = uic.loadUi("D:\\Qt\\QtData\\PyQt\\PyQtLesson\\Qt Designer\\login_test.ui")
        # print(self.ui)                          # ui文件中最顶层的对象
        # print(self.ui.__dict__)                 # 最顶层对象的所有属性(key:value方式显示)
        # print(self.ui.label)                    # 最顶层对象中嵌套的QLabel
        # print(self.ui.label.text())             # 最顶层对象中嵌套的QLabel的文本
        self.user_name = self.ui.lineEdit              # 用户名输入框
        self.password = self.ui.lineEdit_2             # 密码输入框
        login_btn = self.ui.pushButton            # 登录按钮
        forget_btn = self.ui.pushButton_2         # 忘记密码按钮
        text_browser = self.ui.textBrowser        # 文本显示区域

        # 给登录按钮被点击绑定槽函数
        login_btn.clicked.connect(self.login)

    def login(self):
        """实现登录的逻辑"""
        print("正在登录。。。。。。")
        # 提取用户名,密码
        print(self.user_name.text())
        print(self.password.text())

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = MyWindow()
    w.ui.show()
    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)点击登录按钮后槽函数的完善

这里完善一下上述的案例

"""
动态加载ui文件
"""
import sys
from PyQt5.QtWidgets import *
from PyQt5 import uic

class MyWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.ui = None
        self.user_name = None
        self.password_qwidget = None
        self.login_btn = None
        self.forget_btn = None
        self.text_browser = None
        self.init_ui()

    def init_ui(self):
        self.ui = uic.loadUi("D:\\Qt\\QtData\\PyQt\\PyQtLesson\\Qt Designer\\login_test.ui")

        # 提取要操作的控件
        self.user_name = 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)

    def login(self):
        """登录按钮的槽函数"""
        user_name = self.user_name.text()
        password = self.password_qwidget.text()
        if user_name == "admin" and password == "123456":
            self.text_browser.setText("欢迎%s" % user_name)
            self.text_browser.repaint()
        else:
            self.text_browser.setText("用户名或密码错误...请重试")
            self.text_browser.repaint()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = MyWindow()
    w.ui.show()
    app.exec_()

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

展示过程如下

(5)PyQt引入多线程

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

重新运行效果如下

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

原因如下:

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

解决办法如下:

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

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

<2>PyQt使用多线程

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

2.整体代码如下

import sys
import time

from PyQt5 import uic
from PyQt5.Qt import QApplication, QWidget, QThread


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("D:\\Qt\\QtData\\PyQt\\PyQtLesson\\Qt Designer\\thread-1.ui")

        # 从ui文件中加载控件
        lineedit = self.ui.lineEdit
        btn1 = self.ui.pushButton
        btn2 = self.ui.pushButton_2

        # 给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()
    app.exec()

3.运行如下

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

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

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

4.关键代码分析

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

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

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

(6)PyQt多线程案例

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

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

<1>整体代码

import json
import sys
import time

from PyQt5 import uic
from PyQt5.Qt import QApplication, QWidget, QThread
from PyQt5.QtCore import pyqtSignal


class LoginThread(QThread):
    # 创建自定义信号
    start_login_signal = pyqtSignal(str)
    def __init__(self):
        super().__init__()

    def login_by_requests(self, user_password_json):
        # 将json字符串,转换为自定,从而实现传递了用户名以及密码
        user_password_json = json.loads(user_password_json)
        print(user_password_json.get("user_name"))
        print(user_password_json.get("password"))

    def run(self):
        # 通过whileTrue的方式让子线程一直运行,而不是结束
        # 通过这种方式,我们让子线程一直活着,从而有能力接收来自主线程 (UI线程)的任务
        while True:
            print("子线程正在执行....")
            time.sleep(1)


class MyWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.ui = None
        self.user_name_qwidget = None
        self.password_qwidget = None
        self.login_btn = None
        self.forget_password_btn = None
        self.textBrowser = None
        self.login_thread = None
        self.init_ui()

    def init_ui(self):
        self.ui = uic.loadUi("D:\\Qt\\QtData\\PyQt\\PyQtLesson\\Qt Designer\\login_test.ui")

        # 提取要操作的控件
        self.user_name_qwidget = self.ui.lineEdit            # 用户名输入框
        self.password_qwidget = self.ui.lineEdit_2           # 密码输入框
        self.login_btn = self.ui.pushButton                  # 登录按钮
        self.forget_password_btn = self.ui.pushButton_2      # 忘记密码按钮
        self.textBrowser = self.ui.textBrowser                # 文本显示区域

        # 绑定信号与槽函数
        self.login_btn.clicked.connect(self.login)

        # 创建一个子线程(注意这里要将Login_thread变量变为对象的属性,如果不是对象属性,而是一个普通的局部变量的话
        # 会随着init_ui函数执行结束而被释放此时子线程还没有执行完毕所有会产生问题)
        self.login_thread = LoginThread()
        # 将要创建的子线程类中的信号进行绑定
        self.login_thread.start_login_signal.connect(self.login_thread.login_by_requests)
        # 让子线程开始巩工作
        self.login_thread.start()

    def login(self):
        """登录按钮的槽函数"""
        user_name = self.user_name_qwidget.text()
        password = self.password_qwidget.text()
        # 发送信号,让子线程开始登录
        self.login_thread.start_login_signal.emit(json.dumps({"user_name": user_name, "password": password}))

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = MyWindow()
    w.ui.show()
    app.exec_()

<2>代码运行结果

(7)PyQt链接云函数

<1> 云函数的修改

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

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

<2> 本地整体代码

import json
import sys
import time
import requests

from PyQt5 import uic
from PyQt5.Qt import QApplication, QWidget, QThread
from PyQt5.QtCore import pyqtSignal


class LoginThread(QThread):
    # 创建自定义信号
    start_login_signal = pyqtSignal(str)
    def __init__(self, signal):
        super().__init__()
        self.login_complete_signal = signal

    def login_by_requests(self, user_password_json):
        # 将json字符串,转换为自定,从而实现传递了用户名以及密码
        user_password_json = json.loads(user_password_json)
        print(user_password_json.get("user_name"))
        print(user_password_json.get("password"))

        # 使用requests模块发送请求(POST)
        r = requests.post(url = "https://service-ed6mmhrc-1318499709.nj.apigw.tencentcs.com/release/test"
                          , json = user_password_json())
        print("收到腾讯服务器的相应:", r.content.decode())
        ret = r.json()
        print("这里要发送信号给UI线程.....")
        self.login_complete_signal.emit(json.dumps(ret))

    def run(self):
        # 通过whileTrue的方式让子线程一直运行,而不是结束
        # 通过这种方式,我们让子线程一直活着,从而有能力接收来自主线程 (UI线程)的任务
        while True:
            print("子线程正在执行....")
            time.sleep(1)


class MyWindow(QWidget):
    # 创建定义信号
    login_status_signal = pyqtSignal(str)
    def __init__(self):
        super().__init__()
        self.ui = None
        self.user_name_qwidget = None
        self.password_qwidget = None
        self.login_btn = None
        self.forget_password_btn = None
        self.textBrowser = None
        self.login_thread = None
        self.init_ui()

    def init_ui(self):
        self.ui = uic.loadUi("D:\\Qt\\QtData\\PyQt\\PyQtLesson\\Qt Designer\\login_test.ui")

        # 提取要操作的控件
        self.user_name_qwidget = self.ui.lineEdit            # 用户名输入框
        self.password_qwidget = self.ui.lineEdit_2           # 密码输入框
        self.login_btn = self.ui.pushButton                  # 登录按钮
        self.forget_password_btn = self.ui.pushButton_2      # 忘记密码按钮
        self.textBrowser = self.ui.textBrowser                # 文本显示区域

        # 绑定信号与槽函数
        self.login_btn.clicked.connect(self.login)

        # 创建一个信号,用让子线程登录成功之后向主线程发送
        self.login_status_signal.connect(self.login_status)

        # 创建一个子线程(注意这里要将Login_thread变量变为对象的属性,如果不是对象属性,而是一个普通的局部变量的话
        # 会随着init_ui函数执行结束而被释放此时子线程还没有执行完毕所有会产生问题)
        self.login_thread = LoginThread(self.login_status_signal)
        # 将要创建的子线程类中的信号进行绑定
        self.login_thread.start_login_signal.connect(self.login_thread.login_by_requests)
        # 让子线程开始巩工作
        self.login_thread.start()

    def login(self):
        """登录按钮的槽函数"""
        user_name = self.user_name_qwidget.text()
        password = self.password_qwidget.text()
        # 发送信号,让子线程开始登录
        self.login_thread.start_login_signal.emit(json.dumps({"user_name": user_name, "password": password}))

    def login_status(self, status):
        print("status.....", status)
        status_dict = json.loads(status)
        self.textBrowser.setText(status_dict.get("errmsg"))
        self.textBrowser.repaint()

        if __name__ == '__main__':
        app = QApplication(sys.argv)
        w = MyWindow()
        w.ui.show()
        app.exec_()

<3> 重要代码解析

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

<4> 运行结果

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

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

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

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值