Qt 样式表(Qt Style Sheets, QSS)是一种强大的机制,允许开发者使用类似 CSS 的语法来定制 Qt 应用程序的外观。QSS 提供了比传统编程方式更灵活、更高效的界面美化方案,使应用程序能够拥有独特的视觉风格。
QSS 的基本语法与 CSS 类似:
selector { property: value; }
可以通过以下方式应用样式表:
qApp->setStyleSheet("QPushButton { color: red; }");
widget->setStyleSheet("background-color: yellow;");
QFile file(":/styles/mystyle.qss");
file.open(QFile::ReadOnly);
qApp->setStyleSheet(file.readAll());
匹配所有控件:
* { color: blue; }
匹配特定类型的控件:
QPushButton { background-color: gray; }
QLabel { font-size: 14px; }
匹配具有特定类名的控件:
.QFrame { border: 1px solid black; }
匹配具有特定对象名称的控件:
#myButton { font-weight: bold; }
匹配具有特定属性的控件:
QPushButton[flat="true"] { background: transparent; }
匹配作为另一个控件后代的控件:
QDialog QLabel { color: green; }
匹配作为另一个控件直接子控件的控件:
QListWidget > QAbstractItemView { outline: none; }
background-color: red; /* 背景颜色 */
background-image: url(img.png); /* 背景图片 */
background-repeat: no-repeat; /* 背景重复方式 */
background-position: center; /* 背景位置 */
border: 2px solid blue; /* 边框宽度、样式和颜色 */
border-radius: 5px; /* 边框圆角 */
border-top: 1px dashed gray; /* 上边框 */
font-family: Arial; /* 字体族 */
font-size: 12pt; /* 字体大小 */
font-weight: bold; /* 字体粗细 */
color: white; /* 文字颜色 */
margin: 10px; /* 外边距 */
padding: 5px; /* 内边距 */
min-width: 100px; /* 最小宽度 */
max-height: 30px; /* 最大高度 */
opacity: 0.8; /* 不透明度 */
QSS 支持基于控件状态的样式定义:
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 类似的盒模型,包括内容区、内边距、边框和外边距:
QWidget {
margin: 10px; /* 外边距 */
padding: 5px; /* 内边距 */
border: 2px solid; /* 边框 */
width: 200px; /* 宽度 */
height: 100px; /* 高度 */
}
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;
}
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;
}
QProgressBar {
border: 2px solid grey;
border-radius: 5px;
text-align: center;
}
QProgressBar::chunk {
background-color: #05B8CC;
width: 10px;
margin: 0.5px;
}
QPushButton {
background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #FFFFFF, stop:1 #AAAAAA);
}
QWidget {
background-image: url(:/images/background.png);
background-repeat: repeat;
}
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;
}
QPushButton#closeButton {
qproperty-icon: url(:/icons/close.png);
background: transparent;
border: none;
}
qDebug() << "Style sheet:" << widget->styleSheet();
逐步添加样式规则,确定问题所在。
可以开发简单的工具来实时预览样式表效果:
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;
};
将样式表分为多个文件,例如:
虽然 QSS 不直接支持变量,但可以通过编程方式实现:
QString primaryColor = "#4CAF50";
QString secondaryColor = "#2196F3";
QString styleSheet = QString("QPushButton { background-color: %1; } "
"QLabel { color: %2; }")
.arg(primaryColor)
.arg(secondaryColor);
qApp->setStyleSheet(styleSheet);
保持样式表简洁,避免过于复杂的选择器和规则。
不同平台的默认样式可能有所不同,确保样式表在所有目标平台上都能正常工作。
设计一个现代化的登录界面,具有以下特点:
/* 全局样式 */
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;
}
// 在登录窗口构造函数中应用样式表
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 的高级技巧,能够让你的应用在众多同类产品中脱颖而出。