一、Qt 样式表概述
Qt 样式表(Qt Style Sheets, QSS)是一种强大的机制,允许开发者使用类似 CSS 的语法来定制 Qt 应用程序的外观。QSS 提供了比传统编程方式更灵活、更高效的界面美化方案,使应用程序能够拥有独特的视觉风格。
1.1 基本语法
QSS 的基本语法与 CSS 类似:
css
selector { property: value; }
- 选择器(Selector):指定哪些控件将受到样式影响
- 属性(Property):指定要设置的样式属性
- 值(Value):指定属性的具体值
1.2 应用方式
可以通过以下方式应用样式表:
-
全局应用 :对整个应用程序生效
cppqApp->setStyleSheet("QPushButton { color: red; }");
-
局部应用 :对特定窗口或控件生效
cppwidget->setStyleSheet("background-color: yellow;");
-
外部文件 :从文件加载样式表
cppQFile file(":/styles/mystyle.qss"); file.open(QFile::ReadOnly); qApp->setStyleSheet(file.readAll());
二、选择器类型
2.1 通配选择器
匹配所有控件:
css
* { color: blue; }
2.2 类型选择器
匹配特定类型的控件:
css
QPushButton { background-color: gray; }
QLabel { font-size: 14px; }
2.3 类选择器
匹配具有特定类名的控件:
css
.QFrame { border: 1px solid black; }
2.4 ID 选择器
匹配具有特定对象名称的控件:
css
#myButton { font-weight: bold; }
2.5 属性选择器
匹配具有特定属性的控件:
css
QPushButton[flat="true"] { background: transparent; }
2.6 后代选择器
匹配作为另一个控件后代的控件:
css
QDialog QLabel { color: green; }
2.7 子选择器
匹配作为另一个控件直接子控件的控件:
css
QListWidget > QAbstractItemView { outline: none; }
三、常用样式属性
3.1 背景属性
css
background-color: red; /* 背景颜色 */
background-image: url(img.png); /* 背景图片 */
background-repeat: no-repeat; /* 背景重复方式 */
background-position: center; /* 背景位置 */
3.2 边框属性
css
border: 2px solid blue; /* 边框宽度、样式和颜色 */
border-radius: 5px; /* 边框圆角 */
border-top: 1px dashed gray; /* 上边框 */
3.3 字体属性
css
font-family: Arial; /* 字体族 */
font-size: 12pt; /* 字体大小 */
font-weight: bold; /* 字体粗细 */
color: white; /* 文字颜色 */
3.4 间距和边距
css
margin: 10px; /* 外边距 */
padding: 5px; /* 内边距 */
3.5 其他常用属性
css
min-width: 100px; /* 最小宽度 */
max-height: 30px; /* 最大高度 */
opacity: 0.8; /* 不透明度 */
四、状态选择器
QSS 支持基于控件状态的样式定义:
css
QPushButton { background-color: gray; }
QPushButton:hover { background-color: blue; } /* 鼠标悬停 */
QPushButton:pressed { background-color: red; } /* 鼠标按下 */
QPushButton:checked { background-color: green; } /* 选中状态 */
QPushButton:disabled { background-color: lightgray; } /* 禁用状态 */
五、盒模型
QSS 使用与 CSS 类似的盒模型,包括内容区、内边距、边框和外边距:
css
QWidget {
margin: 10px; /* 外边距 */
padding: 5px; /* 内边距 */
border: 2px solid; /* 边框 */
width: 200px; /* 宽度 */
height: 100px; /* 高度 */
}
六、自定义控件样式
6.1 自定义按钮
css
QPushButton {
background-color: #4CAF50;
border: none;
color: white;
padding: 8px 16px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 14px;
margin: 4px 2px;
cursor: pointer;
border-radius: 4px;
}
QPushButton:hover {
background-color: #45a049;
}
QPushButton:pressed {
background-color: #3d8b40;
}
6.2 自定义滚动条
css
QScrollBar:vertical {
border: 1px solid #999999;
background: white;
width: 15px;
margin: 22px 0 22px 0;
}
QScrollBar::handle:vertical {
background: qlineargradient(x1:0, y1:0, x2:1, y2:0, stop:0 #bbbbbb, stop:1 #aaaaaa);
min-height: 20px;
border-radius: 3px;
}
QScrollBar::add-line:vertical {
border: 1px solid #999999;
background: #cccccc;
height: 20px;
subcontrol-position: bottom;
subcontrol-origin: margin;
}
QScrollBar::sub-line:vertical {
border: 1px solid #999999;
background: #cccccc;
height: 20px;
subcontrol-position: top;
subcontrol-origin: margin;
}
6.3 自定义进度条
css
QProgressBar {
border: 2px solid grey;
border-radius: 5px;
text-align: center;
}
QProgressBar::chunk {
background-color: #05B8CC;
width: 10px;
margin: 0.5px;
}
七、高级技巧
7.1 使用渐变
css
QPushButton {
background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #FFFFFF, stop:1 #AAAAAA);
}
7.2 使用图像
css
QWidget {
background-image: url(:/images/background.png);
background-repeat: repeat;
}
7.3 嵌套样式
css
QGroupBox {
border: 1px solid gray;
border-radius: 5px;
margin-top: 1ex; /* leave space at the top for the title */
}
QGroupBox::title {
subcontrol-origin: margin;
subcontrol-position: top center; /* position at the top center */
padding: 0 3px;
background-color: transparent;
}
7.4 自定义图标
css
QPushButton#closeButton {
qproperty-icon: url(:/icons/close.png);
background: transparent;
border: none;
}
八、调试样式表
8.1 使用调试输出
cpp
qDebug() << "Style sheet:" << widget->styleSheet();
8.2 分步应用样式
逐步添加样式规则,确定问题所在。
8.3 使用样式表调试工具
可以开发简单的工具来实时预览样式表效果:
cpp
class StyleSheetEditor : public QWidget
{
Q_OBJECT
public:
StyleSheetEditor(QWidget *parent = nullptr) : QWidget(parent)
{
QVBoxLayout *layout = new QVBoxLayout(this);
// 创建文本编辑器
editor = new QTextEdit(this);
layout->addWidget(editor);
// 创建预览按钮
previewButton = new QPushButton("Preview", this);
layout->addWidget(previewButton);
// 连接信号槽
connect(previewButton, &QPushButton::clicked, this, &StyleSheetEditor::applyStyleSheet);
// 加载初始样式表
editor->setPlainText("QPushButton { color: red; }");
}
signals:
void styleSheetChanged(const QString &styleSheet);
private slots:
void applyStyleSheet()
{
emit styleSheetChanged(editor->toPlainText());
}
private:
QTextEdit *editor;
QPushButton *previewButton;
};
九、最佳实践
9.1 保持样式表模块化
将样式表分为多个文件,例如:
- main.qss:全局样式
- buttons.qss:按钮样式
- scrollbars.qss:滚动条样式
- dialogs.qss:对话框样式
9.2 使用变量
虽然 QSS 不直接支持变量,但可以通过编程方式实现:
cpp
QString primaryColor = "#4CAF50";
QString secondaryColor = "#2196F3";
QString styleSheet = QString("QPushButton { background-color: %1; } "
"QLabel { color: %2; }")
.arg(primaryColor)
.arg(secondaryColor);
qApp->setStyleSheet(styleSheet);
9.3 避免过度使用
保持样式表简洁,避免过于复杂的选择器和规则。
9.4 测试跨平台兼容性
不同平台的默认样式可能有所不同,确保样式表在所有目标平台上都能正常工作。
十、实战案例:设计现代化登录界面
10.1 案例需求
设计一个现代化的登录界面,具有以下特点:
- 简洁美观的设计
- 响应式布局
- 平滑的交互效果
- 自定义控件样式
10.2 样式表示例
css
/* 全局样式 */
QWidget {
background-color: #f5f5f5;
font-family: "Segoe UI", "Roboto", "sans-serif";
}
/* 登录框样式 */
QFrame#loginFrame {
background-color: white;
border-radius: 10px;
border: 1px solid #ddd;
padding: 20px;
margin: 20px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
/* 标题样式 */
QLabel#titleLabel {
font-size: 24px;
font-weight: bold;
color: #333;
margin-bottom: 20px;
}
/* 输入框样式 */
QLineEdit {
border: 1px solid #ccc;
border-radius: 4px;
padding: 8px;
margin: 5px 0;
font-size: 14px;
}
QLineEdit:focus {
border: 1px solid #2196F3;
box-shadow: 0 0 5px rgba(33, 150, 243, 0.5);
}
/* 按钮样式 */
QPushButton {
background-color: #2196F3;
color: white;
border: none;
border-radius: 4px;
padding: 10px;
font-size: 16px;
font-weight: 500;
margin: 10px 0;
}
QPushButton:hover {
background-color: #0b7dda;
}
QPushButton:pressed {
background-color: #0a69b4;
}
/* 链接样式 */
QLabel[link="true"] {
color: #2196F3;
text-decoration: underline;
cursor: pointer;
}
QLabel[link="true"]:hover {
color: #0b7dda;
}
10.3 关键代码
cpp
// 在登录窗口构造函数中应用样式表
LoginWindow::LoginWindow(QWidget *parent) : QWidget(parent)
{
// 创建UI元素
QFrame *loginFrame = new QFrame(this);
loginFrame->setObjectName("loginFrame");
QLabel *titleLabel = new QLabel("Login", loginFrame);
titleLabel->setObjectName("titleLabel");
QLabel *usernameLabel = new QLabel("Username:", loginFrame);
QLineEdit *usernameEdit = new QLineEdit(loginFrame);
QLabel *passwordLabel = new QLabel("Password:", loginFrame);
QLineEdit *passwordEdit = new QLineEdit(loginFrame);
passwordEdit->setEchoMode(QLineEdit::Password);
QPushButton *loginButton = new QPushButton("Login", loginFrame);
QLabel *registerLabel = new QLabel("Register", loginFrame);
registerLabel->setProperty("link", true);
// 设置布局
QVBoxLayout *frameLayout = new QVBoxLayout(loginFrame);
frameLayout->addWidget(titleLabel, 0, Qt::AlignCenter);
frameLayout->addWidget(usernameLabel);
frameLayout->addWidget(usernameEdit);
frameLayout->addWidget(passwordLabel);
frameLayout->addWidget(passwordEdit);
frameLayout->addWidget(loginButton);
frameLayout->addWidget(registerLabel, 0, Qt::AlignCenter);
QVBoxLayout *mainLayout = new QVBoxLayout(this);
mainLayout->addStretch();
mainLayout->addWidget(loginFrame);
mainLayout->addStretch();
// 应用样式表
QFile file(":/styles/login.qss");
file.open(QFile::ReadOnly);
setStyleSheet(file.readAll());
// 连接信号槽
connect(loginButton, &QPushButton::clicked, this, &LoginWindow::onLoginClicked);
connect(registerLabel, &QLabel::linkActivated, this, &LoginWindow::onRegisterClicked);
}
通过 Qt 样式表,可以轻松打造出具有专业水准的个性化界面,提升应用程序的视觉吸引力和用户体验。掌握 QSS 的高级技巧,能够让你的应用在众多同类产品中脱颖而出。