Qt 是一个跨平台的图形界面开发框架,现行的主要版本是 Qt5 和 Qt6,其中 Qt5 已经停止维护。
Python 中有 PyQt6
和 PySide6
两个 Qt6 的包,前者是第三方发布的,后者是 Qt 官方发布的,它们的使用方式几乎完全一致。
通过下面的命令安装 PySide6
:
pip install PySide6
下面代码创建一个简单图形界面程序,上面有一个标签和一个按钮,每次点击按钮,标签上的数字加一。
import sys
from PySide6.QtWidgets import (
QApplication,
QMainWindow,
QWidget,
QLabel,
QPushButton,
QVBoxLayout,
)
class Widget(QWidget):
'''
Widget 作为 窗口的中心部件
'''
def __init__(self):
'''
构造函数
'''
# 父类构造
super().__init__()
# 计数变量
self.__count = 0
# 创建标签,显示文本
self.__label = QLabel(f"Count: {self.__count}")
# 创建按钮,提供点击功能
self.__button = QPushButton("Click Me")
# 绑定信号,按钮被点击时调用 self.increase
self.__button.clicked.connect(self.increase)
# 创建布局
self.__layout = QVBoxLayout()
self.__layout.addWidget(self.__label)
self.__layout.addWidget(self.__button)
self.setLayout(self.__layout)
def increase(self):
'''
increase 计数加一并显示到标签上
'''
self.__count += 1
self.__label.setText(f"Count: {self.__count}")
if __name__ == "__main__":
app = QApplication(sys.argv) # 创建应用
window = QMainWindow() # 创建主窗口
widget = Widget() # 创建部件
window.setCentralWidget(widget) # 设置中心部件
window.show() # 显示窗口
app.exec() # 运行程序,窗口关闭时返回
QMainWindow 提供了构建应用程序用户界面的基本框架:
Menu Bar 是菜单栏
Toolbars 是工具栏,可以有多个工具栏
Dock Widgets 是靠在窗口四边可以拉伸和拖动的部件,可以有多个
Central Widget 是窗口中心部件负责窗口的主要功能
Status BAr 是状态栏,用于显示一些状态信息
Qt 的每个窗口部件(Widget)都可以有自己的布局(Layout),常用的布局有 水平布局(QHBoxLayout
)、垂直布局(QVBoxLayout
)和网格布局(QGridLayout
)。
import sys
from PySide6.QtWidgets import (
QApplication,
QMainWindow,
QWidget,
QPushButton,
QVBoxLayout,
QHBoxLayout,
QGridLayout
)
class Widget(QWidget):
'''
Widget 作为 窗口的中心部件
'''
def __init__(self):
'''
构造函数
'''
# 父类构造
super().__init__()
# 水平布局示例
self.__hbox = QHBoxLayout()
self.__hbox.addWidget(QPushButton("hbox 1"))
self.__hbox.addWidget(QPushButton("hbox 2"))
self.__hbox.addWidget(QPushButton("hbox 3"))
# 垂直布局示例
self.__vbox = QVBoxLayout()
self.__vbox.addWidget(QPushButton("vbox 1"))
self.__vbox.addWidget(QPushButton("vbox 2"))
self.__vbox.addWidget(QPushButton("vbox 3"))
# 网格布局示例
self.__grid = QGridLayout()
self.__grid.addWidget(QPushButton("grid 1"), 0, 0)
self.__grid.addWidget(QPushButton("grid 2"), 0, 1)
self.__grid.addWidget(QPushButton("grid 3"), 1, 0)
self.__grid.addWidget(QPushButton("grid 4"), 1, 1)
# 布局可以包含布局
self.__main_layout = QVBoxLayout()
self.__main_layout.addLayout(self.__hbox)
self.__main_layout.addLayout(self.__vbox)
self.__main_layout.addLayout(self.__grid)
# 设置布局
self.setLayout(self.__main_layout)
if __name__ == "__main__":
app = QApplication(sys.argv) # 创建应用
window = QMainWindow() # 创建主窗口
widget = Widget() # 创建部件
window.setCentralWidget(widget) # 设置中心布局
window.show() # 显示窗口
app.exec() # 运行程序,窗口关闭时返回
Qt 的 信号与槽机制(Signal & Slot) 是 Qt 框架中最核心的特性之一,用于对象之间的通信,类似于事件监听机制,但比传统的回调机制更强大、灵活和安全。
使用方法如下,当信号产生时将会调用槽。
# 绑定信号槽
对象.信号.connect(槽)
# 解除绑定
对象.信号.disconnect(槽)
# 发送信号
对象.信号.emit()
自定义信号时,类必须是 QObject
的子类,信号作为类的属性创建:
class Widget(QWidget): # QWidget 是 QObject 的子类,所以不需要再继承 QObject
my_signal = Signal() # 创建信号
Qt 可以使用 QSS (类似 CSS)进行样式设置。窗口部件调用 setStyleSheet
设置 QSS 字符串即可。
样式的结构如下:
选择器 {
属性: 值;
属性: 值;
属性: 值;
}
选择器决定哪些部件受影响,可以设为 QLabel
、QPushButton
等。
属性和值决定相应的样式,例如 background-color:red
表示背景设为红色。
基础示例 的代码添加样式后如下:
def __init__(self):
# ... 省略
# 设置样式
self.setStyleSheet('''QWidget {
background-color: #2b2b2b;
color: #eeeeee;
font-size: 16px;
font-family: "Microsoft YaHei";
}
QLabel {
font-weight: bold;
padding: 5px;
color: #f0f0a0;
}
QPushButton {
background-color: #3c3f41;
border: 1px solid #555;
border-radius: 5px;
padding: 8px 16px;
color: #ffffff;
}
QPushButton:hover {
background-color: #505354;
}
QPushButton:pressed {
background-color: #2c2f30;
}
''')
一些常用属性如下:
分类 | 属性名 | 示例值 | 说明 |
---|---|---|---|
字体 | font-size |
16px |
字体大小 |
font-family |
"Microsoft YaHei" |
字体名称 | |
font-weight |
normal , bold , 100~900 |
字体粗细 | |
font-style |
normal , italic |
字体样式 | |
color |
#ffffff |
字体颜色 | |
背景 | background-color |
#2b2b2b , transparent |
背景颜色 |
background-image |
url(:/images/bg.png) |
背景图 | |
background-repeat |
no-repeat , repeat-x |
背景图重复方式 | |
background-position |
center , top left |
背景图位置 | |
边框 | border |
1px solid #ccc |
边框样式 |
border-width |
1px |
边框宽度 | |
border-style |
solid , dashed , none |
边框样式 | |
border-color |
#ff0000 |
边框颜色 | |
border-radius |
5px |
圆角 | |
内外边距 | padding |
5px |
内边距 |
margin |
5px |
外边距 | |
尺寸 | min-width |
100px |
最小宽度 |
max-height |
50px |
最大高度 | |
width |
200px |
固定宽度 | |
height |
200px |
固定高度 |