Qt for Python学习笔记—应用程序再探
off999 2024-10-18 08:09 37 浏览 0 评论
前言
本系列上一篇文章(Qt for Python学习笔记—应用程序初探 )中对在 Window 平台上不借助 Qt Designer 工具用纯代码方式开发一个简单的 PySide6 入门 GUI 应用程序进行了介绍(含代码解析)。
本文接着详细介绍如何在 Window 平台上不借助 Qt Designer 工具用纯代码方式来开发一个稍微复杂的 PySide6 GUI 应用程序(含代码解析),让读者有更进一步的体会,供各位 Qt for Python 的初学者们参考。
注:本系列将会以 PySide6 为例进行介绍,原则上同样适用于 PyQt6(只需将代码中导入语句的 PySide6 替换为 PyQt6 即可)。
1. 简介
在上一篇文章中介绍的 PySide6 示例程序,窗口非常简单(单窗体,且只包含一个组件 Widget),就直接在 Python 文件中按面向过程的思路进行编写代码的。但如果需要开发一个复杂些的 GUI 应用程序(如包含众多组件的窗口,或者包含多个窗口,功能也多),则按照面向过程编程就会比较麻烦,编写出的代码也不便于优化和维护。因此,通常会采用面向对象编程来开发 PySide6 GUI应用程序(以类的形式来组织程序代码结构)。
本示例程序将涉及到如下内容:
- 如何定义一个自定义主窗口类
- 如何在类中定义构造函数、设置窗口标题
- 如何创建行编辑器(QLineEdit)对象、按钮(QPushButton)对象,并设置相关属性
- 如何创建网格布局(QGridLayout),并将各组件添加到该网络布局
- 如何创建一个部件(QWidget)对象,将网格布局应用于该部件,并将该部件设置为主窗体的中心部件
- 如何对组件建立起信号与槽之间的连接
- 如何自定义一个槽函数
- 如何创建一个应用程序对象
- 如何创建和显示一个自定义主窗口
- 如何运行和退出应用程序
2. 示例目标及原型
我们确定该示例程序所设想达到的目标,并给出其原型。
一、示例目标:
本示例目标是创建一个 Python GUI 应用程序,其主窗口标题为“PySide6 示例程序”,其右上角有最小化、最大化和关闭按钮,窗口可拉伸。其主窗体中分为上下两个区域:
(一)上面是放置一个行编辑器(QLineEdit):
(1) 缺省显示文本内容为 “用 PySide6 开发的第二个 GUI 应用程序!”
(2) 文本居中对齐,字体设置为蓝色,粗体,13px;
(二)下面放置一排4个按钮(QPushButton),依次为:
(1) 【改色】按钮:点击按钮后,文本字体显示为红色
(2) 【恢复】按钮:点击按钮后,文本字体显示为蓝色
(3) 【清除】按钮:点击按钮后,文本内容清空
(4) 【关闭】按钮:点击按钮后,关闭窗口退出程序
二、示例原型:
在进行 GUI 应用程序编码之前,一般建议先勾画出 GUI 框架(窗体及各部件的布局等)。本示例原型如下:
3. 示例代码及运行
一、编辑代码
利用代码编辑器编辑示例代码,并保存为文件(如:C:\MyPySide6\MyPySide6App2.py)。
from PySide6.QtWidgets import (QApplication, QMainWindow, QWidget, QGridLayout, QLineEdit, QPushButton)
from PySide6.QtCore import (Qt, Slot)
class MyWindow(QMainWindow):
def __init__(self):
super(MyWindow, self).__init__()
self.setWindowTitle("PySide6 示例程序")
self.lineEdit = QLineEdit("用 PySide6 开发的第二个 GUI 应用程序!", alignment=Qt.AlignCenter)
self.lineEdit.setStyleSheet("color: blue; font: bold; font-size: 13px;")
self.btnChange = QPushButton("改色")
self.btnReset = QPushButton("恢复")
self.btnClear = QPushButton("清除")
self.btnQuit = QPushButton("关闭")
self.gridLayout = QGridLayout()
self.gridLayout.addWidget(self.lineEdit, 0, 0, 1, 4)
self.gridLayout.addWidget(self.btnChange, 1, 0, 1, 1)
self.gridLayout.addWidget(self.btnReset, 1, 1, 1, 1)
self.gridLayout.addWidget(self.btnClear, 1, 2, 1, 1)
self.gridLayout.addWidget(self.btnQuit, 1, 3, 1, 1)
self.centralwidget = QWidget()
self.centralwidget.setLayout(self.gridLayout)
self.setCentralWidget(self.centralwidget)
self.btnChange.clicked.connect(self.btnChange_Clicked)
self.btnReset.clicked.connect(self.btnReset_Clicked)
self.btnClear.clicked.connect(self.lineEdit.clear)
self.btnQuit.clicked.connect(self.close)
@Slot()
def btnChange_Clicked(self):
self.lineEdit.setStyleSheet("color: red; font: bold; font-size: 13px;")
@Slot()
def btnReset_Clicked(self):
self.lineEdit.setText("用 PySide6 开发的第二个 GUI 应用程序!")
self.lineEdit.setStyleSheet("color: blue; font: bold; font-size: 13px;")
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
win = MyWindow()
win.show()
sys.exit(app.exec_()) 从控制台终端通过命令方式(或直接在 Visual Studio Code 上点击主窗体上运行按钮)来运行该示例程序(通常会先进入代码所在目录下):
C:\MyPySide6> python MyPySide6App2.py顺利的话应该会出现以下程序窗口(可以试着分别点击四个按钮看看效果):
4. 代码解析
本示例代码共分三部分:
4.1 导入模块(或类)部分
首先,导入相关模块(或类):
from PySide6.QtWidgets import (QApplication, QMainWindow, QWidget, QGridLayout, QLineEdit, QPushButton)
from PySide6.QtCore import (Qt, Slot)PySide6 模块中的子模块提供对相关 Qt API 的访问。
——第1行代码:由于本示例后续代码中会用到 QApplication 类、QMainWindow 类、QWidget类、QGridLayout 类、QLineEdit 类、QPushButton 类,所以需要从 PySide6.QtWidgets 模块导入上述类;
——第2行代码:由于用到 Qt 类和 Slot 类,所以需要从 PySide6.QtCore 模块中导入前面2个类。
注:导入语句中关键词 import 后可以跟多个类(用逗号隔开)时,可以使用括号,也可以不使用括号。
4.2 自定义MyWindow类部分
其次,自定义 MyWindow 类(即主窗体,继承自 QMainWindow 类):
(一)定义类的声明
class MyMainWindow(QMainWindow):
...——第1行代码:是类定义的声明语句。Python 中类的声明使用关键词 class,之后是一个空格,然后是类的名字(MyMainWindow),紧跟着的括号及内容表示该类继承自 QMainWindow 类,最后以一个半角冒号结尾。
——后面代码:类体。
(二)定义类的构造函数
定义类的构造函数(构造时会进行初始化工作)。
(1)首先继承父类构造函数的全部属性,并设置主窗口标题
def __init__(self):
super(MyMainWindow, self).__init__()
self.setWindowTitle("PySide6 示例程序")
......——第1-4行代码:定义自定义 MyMainWindow 类的构造函数
——第2行代码:通过 super() 方法继承父类(QMainWindow )构造函数中的全部属性
注:语法为:super( 自己的类, self ).__init__()
——第3行代码:通过 setWindowTitle() 方法设置主窗体的标题为"PySide6 示例程序"
(2)创建窗体界面组件对象,并设置相应属性
self.lineEdit = QLineEdit("用 PySide6 开发的第二个 GUI 应用程序!", alignment=Qt.AlignCenter)
self.lineEdit.setStyleSheet("color: blue; font: bold; font-size: 13px;")
self.btnChange = QPushButton("改色")
self.btnReset = QPushButton("恢复")
self.btnClear = QPushButton("清除")
self.btnQuit = QPushButton("关闭")——第1行代码:在构造函数中创建1个行编辑器对象(对象名为 lineEdit),并设置其显示文本内容("用 PySide6 开发的第二个 GUI 应用程序!")、对齐方式(居中)。
——第2行代码:行编辑器对象调用其 setStyleSheet() 方法,通过Qt样式表(Qt Style Sheets)来设置自己的外观(文本颜色为蓝色,粗体、字号为13px)。
——第3行代码:在构造函数中创建1个按钮对象(对象名为 btnChange),并设置其文本内容("改色")
——第4行代码:在构造函数中创建1个按钮对象(对象名为 btnReset),并设置其文本内容("恢复")
——第5行代码:在构造函数中创建1个按钮对象(对象名为 btnClear),并设置其文本内容("清除")
——第6行代码:在构造函数中创建1个按钮对象(对象名为 btnQuit),并设置其文本内容("关闭")
注:可以通过Qt样式表(Qt Style Sheets)来设置组件的多种外观,包括颜色、背景色、字体、边框宽度、边框颜色、边框样式等。会在后续的文章对 “Qt 样式表” 专门加以详细介绍的。
(3)创建一个网格布局,并将窗体界面组件对象逐一添加到网格布局
self.gridLayout = QGridLayout()
self.gridLayout.addWidget(self.lineEdit, 0, 0, 1, 4)
self.gridLayout.addWidget(self.btnChange, 1, 0, 1, 1)
self.gridLayout.addWidget(self.btnReset, 1, 1, 1, 1)
self.gridLayout.addWidget(self.btnClear, 1, 2, 1, 1)
self.gridLayout.addWidget(self.btnQuit, 1, 3, 1, 1)——第1行代码:在构造函数中使用 QGridLayout 类创建一个网格布局(对象名为 gridLayout)
——第2行代码:调用 addWidget() 方法将行编辑器对象(lineEdit)添加到该网格布局(gridLayout)中
——第3行代码:调用 addWidget() 方法将按钮对象(btnChange)添加到该网格布局(gridLayout)中
——第4行代码:调用 addWidget() 方法将按钮对象(btnReset)添加到该网格布局(gridLayout)中
——第5行代码:调用 addWidget() 方法将按钮对象(btnClear)添加到该网格布局(gridLayout)中
——第6行代码:调用 addWidget() 方法将按钮对象(btnQuit)添加到该网格布局(gridLayout)中
注:可能读者会对上述代码不太理解,不要着急,这里先有个初步印象,知道这些代码能起什么作用就行了,在后续的文章我会对 “布局管理” 专门加以详细介绍的。
(4)创建一个部件对象,将布局应用于该部件,并将该部件设置为主窗体的中心部件
self.centralwidget = QWidget()
self.centralwidget.setLayout(self.gridLayout)
self.setCentralWidget(self.centralwidget)——第1行代码:在类定义的构造函数中通过实例化 QWidget 类创建一个部件对象(对象名为 centralwidget);
——第2行代码:将之前创建的网格布局(gridLayout)应用于该部件对象(centralwidget);
——第3行代码:调用 setCentralWidget() 方法将该部件对象(centralwidget)设置为主窗体的窗口中心部件(添加到主窗口中)。
注:可能读者会对上述代码不太理解,不要着急,这里先有个初步印象,知道这些代码能起什么作用就行了,有关“中心部件(Central Widget)” 我会在后续的文章“主窗口”中专门加以详细介绍。
(5)为按钮建立信号与槽的连接
self.btnChange.clicked.connect(self.btnChange_Clicked)
self.btnReset.clicked.connect(self.btnReset_Clicked)
self.btnClear.clicked.connect(self.lineEdit.clear)
self.btnQuit.clicked.connect(self.close)在构造函数中分别为3个按钮建立起clicked信号与各自对应槽函数的连接。
——第1行代码:建立起【更改】按钮的 clicked 信号与自定义槽函数 btnChange_Clicked() 之间的连接。该槽函数需要在该类中自行定义。
——第2行代码:建立起【恢复】按钮的 clicked 信号与自定义槽函数 btnReset_Clicked() 之间的连接。
——第3行代码:建立起【清除】按钮的 clicked 信号与行编辑器对象内置的槽函数 clear() 之间的连接。
——第4行代码:建立起【关闭】按钮的 clicked 信号与主窗体对象内置的槽函数 close() 之间的连接。
注:可能读者会对“信号与槽”感觉有点懵,不要着急,“信号与槽” 是 Qt 的一个重要的机制,这里先有个初步印象,知道有这么个东西就行了,在后续的文章我会对 “信号与槽“ 专门加以介绍的。
(三)、定义类的槽函数,为按钮建立信号与槽的连接
(1)定义槽函数 btnChange_Clicked()
@Slot()
def btnChange_Clicked(self):
self.lineEdit.setStyleSheet("color: red; font: bold; font-size: 13px;")——第1行代码:@Slot() 是一个装饰器,表示将下面的函数标识为槽函数。
——第2-3行代码:自定义【更改】按钮点击信号连接的槽函数 btnChange_Clicked()。
——第3行代码:行编辑器调用其 setStyleSheet() 方法,通过Qt样式表(Qt Style Sheets)来更改自己的外观(文本颜色为红色,粗体、字号为13px)。
(2)定义槽函数 btnReset_Clicked()
@Slot()
def btnReset_Clicked(self):
self.lineEdit.setText("用 PySide6 开发的第二个 GUI 应用程序!")
self.lineEdit.setStyleSheet("color: blue; font: bold; font-size: 13px;")——第1行代码:@Slot() 是一个装饰器,表示将下面的函数标识为槽函数。
——第2-4行代码:自定义【更改】按钮点击信号连接的槽函数 btnChange_Clicked()。
——第3行代码:行编辑器调用其 setText() 方法,设置行编辑器的文本内容("用 PySide6 开发的第二个 GUI 应用程序!")。
——第4行代码:行编辑器调用其 setStyleSheet() 方法,通过Qt样式表(Qt Style Sheets)来更改自己的外观(文本颜色为红色,粗体、字号为13px)。
注:可能读者会对“槽函数”还是不太理解,不要着急,“信号与槽” 是 Qt 的一个重要的机制,这里先有个初步印象,知道有这么个东西就行了,在后续的文章我会对 “信号与槽“ 专门加以介绍的。
4.3 测试代码部分
最后,在测试代码部分,对自定义窗口类进行测试(创建应用程序、创建和显示自定义主窗口、运行应用程序直至退出)。
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
win = MyMainWindow()
win.show()
sys.exit(app.exec_())——第1行代码:表示只有该 Python 文件被直接运行时,该语句之后的代码才会被执行;而如果是该 Python 文件被 import 到 Python 文件中运行时,则该语句之后的代码不会被执行。
注1:一个 Python 文件通常有两种运行方式,第一种是作为脚本被直接运行;第二种是被 import 到其他 Python 文件中(作为模块)被调用运行。
注2:测试代码并非必须,只是一种良好的编码习惯。
——第2行代码:导入 Python 内置的 sys 模块,接下的 sys.argv 和 sys.ext() 会用到该模块。
注:该导入语句也可以与其他导入语句一起放置在文件头部。
——第4行代码:使用 QApplication 类创建一个应用程序对象(app),括号内的 sys.argv 表示构造时含的传递参数。
注:QApplication 是管理 Qt GUI 应用程序的控制流程和主要设置的类。任何 Qt GUI 应用程序都必须包含一个 QApplication 类的实例对象。对于非GUI的Qt应用程序,可以使用 QCoreApplication 类。
——第5行代码:使用自定义的 MyMainWindow 类创建应用程序的主窗口(构造时会完成窗口初始化)。
——第6行代码:调用 MyMainWindow 类的 show() 方法来显示该主窗口。
——第7行代码:该行代码实际上包含两个调用方法,作用是运行应用程序,直至退出。
(1)、执行 QApplication 类的 exec_() 方法,使 Qt GUI 进入程序的主事件循环,直到程序中调用 exit()、或 quit() 时,或应用程序的主窗口被关闭时才会结束,并在退出时返回一个状态码。
(2)、sys.exit() 方法的作用是(当接收到退出状态码)退出当前应用程序。
注1:主事件循环从窗口系统接收事件,并将其分派给应用程序部件进行处理。如果没有调用方法,那么在程序运行的时候还没有进入程序的主事件循环就直接结束了,所以运行的时候窗口会闪退。
注2:直接使用 app.exec_() ,程序也可以正常运行,但是关闭窗口后进程却不会退出。
结束语
本系列介绍如何在 Python 中使用 Qt for Python 进行 GUI 应用程序开发。
本文是《Qt for Python 学习笔记》系列第四篇,如何在 Window 平台上不借助 Qt Designer 工具用纯代码方式来开发一个稍微复杂的 PySide6 应用程序(含较为详细的代码解析),让读者有更进一步的体会。
后续会借助 Qt Designer 工具进行可视化界面设计,所以接下来就对 Qt Designer 进行一个入门介绍,敬请期待!
希望本文能对您有所帮助!若文中存在疏忽不足或错误,还请不吝赐教!
相关推荐
- 怎么把win7电脑恢复出厂设置
-
1.首先我们打开电脑找到“计算机”点击打开。2.进入页面然后我们点击“Windows7(C:)”打开C盘。3.我们在C盘界面找到Windows7并点击打开。4.进入到Win7文件夹中找到并双击“Sys...
- ctrl c 和 ctrl v 怎么按(一键复制粘贴)
-
左手小指按Ctrl键,食指按C键或者V键具体在按Ctrl+C的时候,无名指放在Z键上,中指放在X键上,食指按C键如果你也用这种方式的话,可能和我一样,第一次按的时候不习惯手指这样去分工的感觉,但是你...
- 玩游戏cpu温度多少正常(玩游戏cpu温度多少正常 贴吧)
-
在游戏过程中,CPU温度的正常范围通常在40°C至80°C之间。然而,具体的正常温度取决于CPU型号、散热系统和环境条件等因素。一般来说,如果CPU温度超过80°C,就可能存在过热的风险,需要采取措施...
- idm下载器(如何卸载idm下载器)
-
截至2023年9月3日,IDM(InternetDownloadManager)是一款非常受欢迎的下载工具,但它并没有被禁用。IDM可以帮助用户更快速、稳定地下载文件,提供了多线程下载、断点续传等...
- 电脑按f8后无法开机,三个键搞定
-
电脑开机按F8没有反应可能有多种原因,以下是一些可能的解决方法:尝试重启电脑:有时候,系统会出现临时问题,重启可能有助于解决。检查键盘连接和状态:确保键盘连接正常,没有故障。如果在其他地方测试过键盘是...
- 重装win7系统不能正常启动(win7重装系统后进不了系统)
-
1、点击Win10正式版桌面找到“此电脑”图标,右击并从弹出的右键菜单中选择“属性”项。2、此时将打开“控制”窗口,在左侧找到“高级系统设置”按钮点击进入详细设置界面。3、待打开“系统属性”窗口后,切...
- win7professional是什么版本
-
Windows7Professional是专业版。Windows7包含6个版本,分别为Windows7Starter(初级版)、Windows7HomeBasic(家庭普通版)、Win...
- tplink路由器怎么管理(tplink路由器管理app叫什么)
-
1、进入到路由器的管理界面,点击设置向导然后点下一步。2、选择工作模式,选择AP:接入点模式,点击下一步1.AP是WirelessAccessPoint的简称,中文名称:无线接入点;AP模式也...
- 怎样把wifi网速调到最快(怎样把wifi网速调到最快速度)
-
解决的方式很多,试试以下方法: 一、路由器摆放位置不正确 为了让自家的房间显得干净、整洁,很多人会选择将路由器放在不显眼的地方,比如门后、墙角、电脑桌下面,这样确实不影响美观,但是网络信号容易被...
- 十大口碑最好的台式电脑(目前最好的台式)
-
一:联想电脑联想公司是全世界500强公司,也是全世界最大的pc电脑生产商之一。目前在点信息科技产业内全方位发展,是一家具有创造力的科技大公司,在全世界也就具有极高的品牌价值。二:戴尔电脑戴尔也是PC电...
- 显卡天梯图3050ti(显卡天梯图快科技)
-
RTX3050Ti的最新跑分达到了71803。根据Geekbench的信息,RTX3050Ti搭载20组CU,也就是2560个CUDA核心,GPU频率为1.49GH...
- office完整版下载(office2019完整版下载)
-
word是office软件中的一部份,完全的安装了office软件就等于安装了word。安装具体步骤如下:1、搜索,下载Office安装包。2、下载完成后,将Office安装包解压。选中Offic...
- qq邮箱网页登陆(qq邮箱网页登陆提示安全风险要验证码)
-
qq邮箱的登录方法:1登录QQ后,正常情况下头像旁边有一个邮箱图标,点击直接登录QQ邮箱2如果没有在主面板上显示的话,可以点击界面管理器添加3在界面管理的右侧,找到QQ邮箱并设置为选状态这样就可直接从...
欢迎 你 发表评论:
- 一周热门
-
-
抖音上好看的小姐姐,Python给你都下载了
-
全网最简单易懂!495页Python漫画教程,高清PDF版免费下载
-
Python 3.14 的 UUIDv6/v7/v8 上新,别再用 uuid4 () 啦!
-
python入门到脱坑 输入与输出—str()函数
-
飞牛NAS部署TVGate Docker项目,实现内网一键转发、代理、jx
-
宝塔面板如何添加免费waf防火墙?(宝塔面板开启https)
-
Python三目运算基础与进阶_python三目运算符判断三个变量
-
(新版)Python 分布式爬虫与 JS 逆向进阶实战吾爱分享
-
慕ke 前端工程师2024「完整」
-
失业程序员复习python笔记——条件与循环
-
- 最近发表
- 标签列表
-
- python计时 (73)
- python安装路径 (56)
- python类型转换 (93)
- python进度条 (67)
- python吧 (67)
- python的for循环 (65)
- python格式化字符串 (61)
- python静态方法 (57)
- python列表切片 (59)
- python面向对象编程 (60)
- python 代码加密 (65)
- python串口编程 (77)
- python封装 (57)
- python写入txt (66)
- python读取文件夹下所有文件 (59)
- python操作mysql数据库 (66)
- python获取列表的长度 (64)
- python接口 (63)
- python调用函数 (57)
- python多态 (60)
- python匿名函数 (59)
- python打印九九乘法表 (65)
- python赋值 (62)
- python异常 (69)
- python元祖 (57)
