PYQT学习笔记-从简单窗口到多功能主窗口的实现
PyQt5学习笔记:从简单窗口到多功能主窗口的实现
- 1. 环境准备
- 2. 创建第一个PyQt窗口
- 2.1 代码实现
- 2.2 代码解析
- 2.2.1 创建应用程序
- 2.2.2 创建窗口
- 2.2.3 创建布局
- 2.2.4 添加复选框和按钮
- 2.2.5 信号与槽
- 2.2.6 显示窗口
- 3. 关键点解释
- 3.1 `arg` 是什么?
- 3.2 `lambda` 的作用
- 3.3 信号与槽
- 4. 运行效果
- 5. 使用Qt Designer设计界面
- 5.1 创建UI文件
- 5.2 转换UI文件为Python代码
- 6. 编写Python代码
- 6.1 主程序代码
- 6.2 UI代码(自动生成)
- 7. 功能说明
- 7.1 状态栏和菜单栏
- 7.2 控件功能
- 7.3 主题样式
- 8. 运行效果
1. 环境准备
在开始之前,请确保你已经安装了PyQt5和qt_material
库。如果尚未安装,可以通过以下命令进行安装:
pip install PyQt5 qt_material
2. 创建第一个PyQt窗口
2.1 代码实现
以下是创建一个简单PyQt窗口的完整代码:
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QVBoxLayout
from PyQt5.QtWidgets import QPushButton, QCheckBox, QLabel
import sys
# 定义按钮状态更新函数
def btn_state_update(arg):
print("抽烟:", arg)
btn_state_update_func(0, "抽烟", arg)
# 定义统一处理函数
def btn_state_update_func(flag, text, arg):
"""
统一处理函数
:param flag: 用于区分按钮的数字
:param text: 可选文本描述
:param arg: 选中状态 2选中 0未选中
"""
print(f"{flag}:{text} -> {arg}")
# 定义提交按钮的槽函数
def on_submit():
print("抽烟:", btn1.isChecked())
print("喝酒:", btn2.isChecked())
print("烫头:", btn3.isChecked())
if __name__ == "__main__":
# 1. 创建应用程序
app = QApplication(sys.argv)
# 2. 创建窗口
w = QWidget()
w.setWindowTitle("对话框") # 设置窗口标题
w.resize(200, 120) # 设置窗口大小
# 创建水平布局
root_layout = QHBoxLayout(w)
# 创建复选框
btn1 = QCheckBox("抽烟")
btn2 = QCheckBox("喝酒")
btn3 = QCheckBox("烫头")
btn3.setChecked(True) # 默认选中
btn2.setChecked(True) # 默认选中
# 给每个复选框关联状态变化槽函数
btn1.stateChanged.connect(btn_state_update)
btn2.stateChanged.connect(lambda arg: btn_state_update_func(1, "喝酒", arg))
btn3.stateChanged.connect(lambda arg: btn_state_update_func(2, "烫头", arg))
# 将组件添加到布局
root_layout.addWidget(QLabel("谦哥的三大爱好:"))
root_layout.addWidget(btn1)
root_layout.addWidget(btn2)
root_layout.addWidget(btn3)
# 添加提交按钮
btn_submit = QPushButton("提交")
btn_submit.clicked.connect(on_submit)
root_layout.addWidget(btn_submit)
# 3. 显示窗口
w.show()
# 4. 等待窗口关闭
sys.exit(app.exec_())
2.2 代码解析
2.2.1 创建应用程序
app = QApplication(sys.argv)
QApplication
是 PyQt 中应用程序的主类,它管理 GUI 应用程序的控制流和主要设置。sys.argv
是一个命令行参数列表,PyQt 使用它来处理命令行参数。
2.2.2 创建窗口
w = QWidget()
w.setWindowTitle("对话框")
w.resize(200, 120)
QWidget
是 PyQt 中所有用户界面对象的基类。setWindowTitle
设置窗口标题。resize
设置窗口的宽度和高度。
2.2.3 创建布局
root_layout = QHBoxLayout(w)
QHBoxLayout
是水平布局管理器,用于将窗口中的组件水平排列。- 你也可以使用
QVBoxLayout
来实现垂直排列。
2.2.4 添加复选框和按钮
btn1 = QCheckBox("抽烟")
btn2 = QCheckBox("喝酒")
btn3 = QCheckBox("烫头")
QCheckBox
是一个复选框控件,用户可以通过点击来选中或取消选中。
2.2.5 信号与槽
btn1.stateChanged.connect(btn_state_update)
btn2.stateChanged.connect(lambda arg: btn_state_update_func(1, "喝酒", arg))
stateChanged
是复选框的状态变化信号,当复选框的状态发生改变时,会触发连接的槽函数。lambda
是一种创建匿名函数的方式,用于将信号传递的参数进一步处理后传递给目标函数。
2.2.6 显示窗口
w.show()
sys.exit(app.exec_())
show()
方法用于显示窗口。app.exec_()
是 PyQt 的主循环,它会启动应用程序并等待窗口关闭。
3. 关键点解释
3.1 arg
是什么?
在 btn_state_update
函数中,arg
是从信号 stateChanged
传递过来的参数,表示复选框的当前状态。在 PyQt 中,stateChanged
信号通常用于 QCheckBox
,并传递一个整数值:
0
:未选中(Unchecked)2
:选中(Checked)
3.2 lambda
的作用
lambda
是一种创建匿名函数的方式,允许你在一行代码中定义一个简单的函数。例如:
btn2.stateChanged.connect(lambda arg: btn_state_update_func(1, "喝酒", arg))
lambda arg: ...
定义了一个匿名函数,接收一个参数arg
。- 这个匿名函数的作用是调用
btn_state_update_func
,并将参数1
、"喝酒"
和arg
传递给它。
3.3 信号与槽
信号与槽是 PyQt 的核心机制之一。信号是控件发出的消息,槽是处理这些消息的函数。通过 connect
方法,可以将信号连接到槽函数。当信号被触发时,槽函数会被调用。
4. 运行效果
运行上述代码后,你将看到一个包含三个复选框和一个提交按钮的窗口。当复选框的状态发生变化时,控制台会打印相应的状态信息。点击提交按钮时,控制台会打印每个复选框的选中状态。
5. 使用Qt Designer设计界面
5.1 创建UI文件
- 打开 Qt Designer(通常在 PyQt 安装目录下)。
- 创建一个新的主窗口(
QMainWindow
)。 - 在窗口中添加以下控件:
- QSpinBox:用于数值输入。
- QPushButton:用于触发事件。
- QComboBox:下拉选择框。
- QSlider 和 QDial:滑块和旋钮控件。
- QLCDNumber:用于显示数字。
- QDateEdit:日期选择框。
- QLabel:用于显示文本。
- QMenuBar 和 QToolBar:菜单栏和工具栏。
- 保存 UI 文件(例如命名为
my_main_window.ui
)。
5.2 转换UI文件为Python代码
使用 pyuic5
工具将 .ui
文件转换为 Python 代码:
pyuic5 -x my_main_window.ui -o Ui_my_main_window.py
转换后的代码将生成一个 Ui_MainWindow
类,用于定义界面布局。
6. 编写Python代码
6.1 主程序代码
以下是完整的主程序代码,结合了自动生成的 UI 代码和自定义功能。
# -*- coding: utf-8 -*-
"""
PyQt5学习笔记:创建一个多功能的主窗口
"""
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow
from qt_material import apply_stylesheet, list_themes
from ui.Ui_my_main_window import Ui_MainWindow # 导入自动生成的UI类
class MyMainWindow(QMainWindow):
"""
主窗口类,继承自 QMainWindow
"""
def __init__(self):
super().__init__()
self.ui = Ui_MainWindow() # 创建 UI 对象
self.ui.setupUi(self) # 设置 UI 布局
self.counter = 0 # 初始化计数器
self.init_ui() # 初始化界面功能
def on_click(self):
"""
按钮点击事件
"""
self.statusBar().showMessage(f"按钮按下了{self.counter}") # 在状态栏显示消息
self.counter += 1 # 计数器加1
def on_refresh(self):
"""
刷新功能
"""
print("refresh!")
def init_ui(self):
"""
初始化界面功能
"""
self.ui.pushButton3.clicked.connect(self.on_click) # 绑定按钮点击事件
self.ui.actionexit.triggered.connect(QApplication.quit) # 绑定退出菜单项
self.ui.actionrefresh.triggered.connect(self.on_refresh) # 绑定刷新菜单项
if __name__ == '__main__':
app = QApplication(sys.argv) # 创建应用程序对象
# 应用主题样式
apply_stylesheet(app, theme='dark_teal.xml')
print("可用主题:", list_themes()) # 打印可用的主题列表
w = MyMainWindow() # 创建主窗口实例
w.show() # 显示窗口
sys.exit(app.exec_()) # 运行应用程序并等待窗口关闭
6.2 UI代码(自动生成)
以下是 Ui_MainWindow
类的代码,由 pyuic5
工具从 .ui
文件生成:
# -*- coding: utf-8 -*-
"""
自动生成的 UI 代码
"""
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
"""
设置 UI 布局
"""
MainWindow.setObjectName("MainWindow")
MainWindow.resize(526, 476)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout.setObjectName("gridLayout")
# 添加控件
self.spinBox = QtWidgets.QSpinBox(self.centralwidget)
self.gridLayout.addWidget(self.spinBox, 0, 2, 1, 1)
self.mine = QtWidgets.QPushButton(self.centralwidget)
self.gridLayout.addWidget(self.mine, 0, 3, 1, 1)
self.spinBox_2 = QtWidgets.QSpinBox(self.centralwidget)
self.gridLayout.addWidget(self.spinBox_2, 2, 0, 1, 1)
self.dateEdit = QtWidgets.QDateEdit(self.centralwidget)
self.gridLayout.addWidget(self.dateEdit, 3, 0, 1, 1)
self.plus = QtWidgets.QPushButton(self.centralwidget)
self.gridLayout.addWidget(self.plus, 0, 0, 1, 1)
self.label = QtWidgets.QLabel(self.centralwidget)
self.gridLayout.addWidget(self.label, 2, 2, 1, 1)
self.comboBox = QtWidgets.QComboBox(self.centralwidget)
self.gridLayout.addWidget(self.comboBox, 0, 1, 1, 1)
self.horizontalSlider = QtWidgets.QSlider(self.centralwidget)
self.gridLayout.addWidget(self.horizontalSlider, 3, 1, 1, 1)
self.pushButton3 = QtWidgets.QPushButton(self.centralwidget)
self.gridLayout.addWidget(self.pushButton3, 4, 0, 1, 3)
self.lcdNumber = QtWidgets.QLCDNumber(self.centralwidget)
self.gridLayout.addWidget(self.lcdNumber, 5, 0, 1, 2)
self.dial = QtWidgets.QDial(self.centralwidget)
self.gridLayout.addWidget(self.dial, 5, 2, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 526, 22))
self.menufile = QtWidgets.QMenu(self.menubar)
self.menuedit = QtWidgets.QMenu(self.menubar)
self.menuinfo = QtWidgets.QMenu(self.menubar)
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
MainWindow.setStatusBar(self.statusbar)
self.toolBar = QtWidgets.QToolBar(MainWindow)
MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
self.toolBar_2 = QtWidgets.QToolBar(MainWindow)
MainWindow.addToolBar(QtCore.Qt.LeftToolBarArea, self.toolBar_2)
self.toolBar_3 = QtWidgets.QToolBar(MainWindow)
MainWindow.addToolBar(QtCore.Qt.RightToolBarArea, self.toolBar_3)
self.toolBar_4 = QtWidgets.QToolBar(MainWindow)
MainWindow.addToolBar(QtCore.Qt.BottomToolBarArea, self.toolBar_4)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
"""
设置 UI 文本
"""
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "主窗体测试"))
self.mine.setText(_translate("MainWindow", "mine"))
self.plus.setText(_translate("MainWindow", "plus"))
self.label.setText(_translate("MainWindow", "3245646865给v法国国家"))
self.pushButton3.setText(_translate("MainWindow", "5665"))
self.menufile.setTitle(_translate("MainWindow", "file"))
self.menuedit.setTitle(_translate("MainWindow", "edit"))
self.menuinfo.setTitle(_translate("MainWindow", "info"))
self.toolBar.setWindowTitle(_translate("MainWindow", "toolBar"))
self.toolBar_2.setWindowTitle(_translate("MainWindow", "toolBar_2"))
self.toolBar_3.setWindowTitle(_translate("MainWindow", "toolBar_3"))
self.toolBar_4.setWindowTitle(_translate("MainWindow", "toolBar_4"))
7. 功能说明
7.1 状态栏和菜单栏
- 状态栏:通过
self.statusBar()
获取状态栏,并使用showMessage
方法显示消息。 - 菜单栏:通过
QMenuBar
和QAction
创建菜单项,例如“退出”和“刷新”功能。
7.2 控件功能
- QSpinBox:数值输入框,支持上下调整数值。
- QPushButton:按钮控件,绑定点击事件。
- QSlider 和 QDial:滑块和旋钮控件,通过信号绑定实现联动。
- QComboBox:下拉选择框,支持用户选择。
- QLCDNumber:数字显示控件,可用于显示动态数值。
- QDateEdit:日期选择框,支持用户选择日期。
7.3 主题样式
使用 qt_material
库为应用程序应用主题样式。例如:
apply_stylesheet(app, theme='dark_teal.xml')
你可以通过 list_themes()
查看所有可用的主题。
8. 运行效果
运行程序后,你将看到一个包含多种控件的主窗口。窗口中包含:
- 状态栏和菜单栏。
- 按钮、滑块、旋钮、下拉框等控件。
- 动态更新的 LCD 数字显示。
点击按钮会在状态栏显示消息,滑动滑块或旋转旋钮会联动更新 LCD 数字显示。