概念
-
Qt的样式表主要是受到CSS的启发,通过调用
setStyleSheet()
,可以为一个独立的子部件、整个窗口、甚至整个应用程序制定一个样式表。 -
样式表具有继承关系,例如为一个QWidget类设置了样式表,那么QWidget类及其子类都会使用这个样式表
-
可以在
Qt
帮助文档中检索Qt Style Sheets Reference
关键字查看相关说明。
语法
基本语法格式
下面列出了一些基本组合,可以任意组合,各个组合间通过,
分割即可。
选择器
{
属性: 值;
}
QPushButton
{
color: red;
}
选择器 : 状态
{
属性: 值;
}
QPushButton : hover
{
color: red;
}
选择器 :: 辅助控制器
{
属性 : 值;
}
QCheckBox :: indicator
{
color : red;
}
选择器 : 状态
{
属性 : 值;
}
QPushButton : hover
{
color : red;
}
选择器 :: 辅助控制器 : 状态
{
属性 : 值;
}
QTabBar::tab:selected, QTabBar::tab:hover
{
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #E0E0E0, stop: 1 #FFFFFF);
}
选择器 (selector)
示例1
样式同时应用于QLineEdit、QPushButton
#
QLineEdit, QPushButton
{
color: green;
background-color: rgb(0, 0, 0);
}
示例2
样式应用于readOnly
属性为true
的QLineEdit
和checked
属性为true
的QCheckBox
。
QLineEdit[read-only="true"], QCheckBox[read-only="true"]
{
color: green;
background-color: rgb(0, 0, 0);
}
示例3
为界面组件使用QObject::setProperty()
设置动态属性,样式将应用于属性“required”
为true
的组件。
lineEdit->setProperty("required", "true");
checkBox->setProperty("required", "true");
*[required="true"]
{
background-color: lime;
}
子控件 (sub-control)
子控件是相对于选择器而存在的,可以理解为选择了一个子部件,例如对于一个QCheckBox
,可以分成两部分:文本部分和可以可以点击的复选框部分,我们想要单独设置整个可点击的复选框,就会用到子控件::indicator
。
下面给出一些示例:
QMainWindow::separator{
border: 1px solid #999999;
border-style: outset;
width: 4px;
height: 4px;
}
Splitter::handle{
border: 1px solid #999999;
border-style: outset;
width: 4px;
height: 4px;
}
QSplitter::handle:hover{/*splitter->handle(1)->setAttribute(Qt::WA_Hover, true);才生效*/
border-color: #EA2;
}
QSplitter::handle:pressed{
border-color: #59F;
}
伪状态 (pseudo-states)
每个窗口部件都有各种状态(例如鼠标悬停在该控件上),通过加上伪装态,可以对部件在某个具体状态下的样式表进行设置。
伪状态取反:在伪状态前加一个感叹号!
。例如下面是定义了readonly
属性为false
的QLineEdit
的字体颜色和背景色:
QLineEdit:!read-only
{
color: green;
background-color: rgb(0, 0, 0);
}
伪状态串联使用:相当于“逻辑与”的计算。下面是当鼠标移动到一个被勾选了的QCheckBox
组件上方时,其样式
QCheckBox:checked:hover
{
color: red;
}
伪状态并联使用:相当于“逻辑或”。下面表示当鼠标移动到QCheckBox
上方或者QCheckBox
组件被勾选时,样式都被应用:
子控件使用伪状态:例如下面定义了QCheckBox
的indicator
在checked
和unchecked
两种状态下的背景色:
QCheckBox::indicator:checked
{
background-color: yellow;
}
QCheckBox::indicator:unchecked
{
background-color: blue;
}
盒模型 (The Box model)
每个界面组件都可以用盒模型来表示,模型由四个同心矩形表示:
缺省的情况下,margin
、border-width
、padding
属性缺省值为0,这种情况下,四个同心矩形就是重合的一个矩形。
CONTENT
:是最里面的矩形,显示内容的矩形区域,它绘制窗口部件内容(如文字,图片)。如QLineEdit
用于显示文字的区域,min-width
、max-width
、min-height
和max-height
属性定义最大/最小宽度或高度,就是定义这个矩形区。例如:
QLineEdit
{
min-height: 10px;
}
QLineEdit
{
min-height: 50px;
}
PADDING
:是包围content
的矩形区域,主要是窗口部件内容与边缘线(border)之间的缝隙,通过padding属性
可以定义padding
的宽度,padding-top
、padding-bottom
、padding-left
、padding-right
分别定义padding
的上下左右。例如:
QLineEdit
{
padding-top: 0px;
padding-right: 0px;
padding-left: 0px;
padding-bottom: 20px;
}
QLineEdit
{
padding-top: 30px;
padding-right: 0px;
padding-left: 30px;
padding-bottom: 0px;
}
- BORDER:是包围
padding
的边框,通过border
属性(border-width
、border-style
、border-color
)可以定义边框的线宽、线型和颜色,也可以分别定义border
的上、下、左、右的线宽和颜色。使用border-radius
可以定义边框转角的圆弧半径,从而构造具有圆角矩形的编辑或按钮等组件。例如:
QLineEdit {
border-width: 3px;
border-radius: 10px;
border-color: green;
padding-left: 20px;
}
#通过border-radius、min-width、min-height等属性可以设计圆形的按钮
QPushButton
{
border: 2px groove red;
border-radius: 30px;
min-width: 60px;
min-height: 60px;
}
通过border-image
属性还可以为组件设置背景图片,图片会填充border
矩形框之内的区域,一般使用材质图片设置背景,以使界面具有统一的特点。而background-image
则是原比例填充,若控件大小小于图片大小,则仅显示一部分图片,若控件大小大于图片大小,则将图片进行重复。例如:
QTextEdit
{
border-image: url("369.jpg");
}
QTextEdit
{
background-image: url("369.jpg");
}
样式表使用方法
方法一: 使用Qt Designer的样式表编辑器
优点:操作便捷,直观。
缺点:这样设计的样式表对应用程序是固定的,无法取得换肤的效果,而且需要为每个窗体都涉及样式表,重复性工作太大.
方式二: setStyleSheet函数
使用QApplication
的setStyleSheet
函数可以为应用程序全局设置样式
使用QXXX::setStyleSheet
函数可以为一个窗口、一个对话框、一个界面组件设置样式。例如调用主窗口MainWindow
以及其子控件QPushButton
的setStyleSheet
函数。
还可以预先将编写好的样式表存储在.qss
文件中,使用setStyleSheet
函数加载.qss
文件。
setStyleSheet("MyQssFile.qss");
样式的明确性
为了避免样式冲突,系统定义了以下一系列的样式明确性
确定法则的明确性,Qt样式表遵循CSS2的规定
- 具有伪状态的选择器被认为比没有伪状态的选择器明确性更强。例如:下面两条语法中,第一条的明确性更高,因此第一条生效
QPushButton:hover
{
color: white;
}
QPushButton
{
color: green;
}
- 如果两个选择器具有相同的明确性,则以法则出现的先后顺序为准,后出现的法则起作用。例如:下面的第二个生效
QPushButton:hover
{
color: white;
}
QPushButton:enabled
{
color: green;
}
- 父子关系的两个类作为选择器,具有相同的明确性。例如:下面两个选择器的明确性相同,所以只依赖于语句的先后顺序,因此第二个生效
QPushButton
{
color: white;
}
QAbstractButton
{
color: green;
}
样式定义的级联性
- 样式定义可以在qApp、窗口或一个具体组件中定义,任何一个组件的样式是其父组件、父窗口和qApp的样式的融合
- 当出现冲突时,组件会使用离自己最近的样式定义,即按顺序使用组件自己的样式、或父组件的样式定义、或父窗口的样式定义,或qApp的样式定义,而不考虑样式选择器的确定性
例如上面的多个setStyleSheet
叠加,最终生效的是ui->pushButton->setStyleSheet("QPushButton {color: green}");
。
示例汇总
QGroupBox
QGroupBox
{
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #E0E0E0, stop: 1 #FFFFFF);
}
QGroupBox
{
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #E0E0E0, stop: 1 #FFFFFF);
max-width:200px;
}
QGroupBox
{
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #E0E0E0, stop: 1 #FFFFFF);
padding-bottom: 10px;
}
QGroupBox
{
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #E0E0E0, stop: 1 #FFFFFF);
padding-top: 30px;
}
QGroupBox
{
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #E0E0E0, stop: 1 #FFFFFF);
padding-left: 60px;
}
QGroupBox
{
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #E0E0E0, stop: 1 #FFFFFF);
padding-bottom: 15px;
padding-top: 20px;
padding-left: 3px;
padding-right: 3px;
}
QGroupBox
{
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #E0E0E0, stop: 1 #FFFFFF);
padding-bottom: 15px;
padding-top: 20px;
padding-left: 3px;
padding-right: 3px;
border: 1px solid #FF0000;
}
QGroupBox
{
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #E0E0E0, stop: 1 #FFFFFF);
padding-bottom: 15px;
padding-top: 20px;
padding-left: 3px;
padding-right: 3px;
border: 1px solid #FF0000;
border-radius: 20px;
}
QGroupBox
{
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #E0E0E0, stop: 1 #FFFFFF);
padding-bottom: 15px;
padding-top: 20px;
padding-left: 3px;
padding-right: 3px;
border: 1px solid #FF0000;
border-radius: 20px;
margin-left: 30px;
}
QGroupBox
{
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #E0E0E0, stop: 1 #FFFFFF);
padding-bottom: 15px;
padding-top: 20px;
padding-left: 3px;
padding-right: 3px;
border: 4px solid #FF0000;
border-radius: 20px;
margin-left: 30px;
margin-bottom: 30px;
}
QGroupBox
{
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #E0E0E0, stop: 1 #FFFFFF);
padding-bottom: 15px;
padding-top: 20px;
padding-left: 3px;
padding-right: 3px;
border: 2px solid #FF0000;
border-radius: 20px;
margin-left: 30px;
margin-bottom: 30px;
}
QGroupBox::title {
subcontrol-origin: border;
subcontrol-position: top center;
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #FF0ECE, stop: 1 #FFFFFF);
}
QListView
QListView {
show-decoration-selected: 1; /* make the selection span the entire width of the view */
}
QListView::item:alternate {
background: #EEEEEE;
}
QListView::item:selected {
border: 1px solid #6a6ea9;
}
QListView::item:selected:!active {
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #ABAFE5, stop: 1 #8588B2);
}
QListView::item:selected:active {
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #6a6ea9, stop: 1 #888dd9);
}
QListView::item:hover {
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #FAFBFE, stop: 1 #DCDEF1);
}
QListView {
show-decoration-selected: 1; /* make the selection span the entire width of the view */
font-size: 20px;
font-weight: bold;
font-family: "New Century Schoolbook";
}
QListView::item:alternate {
background: #EEEEEE;
}
QListView::item:selected {
border: 1px solid #6a6ea9;
}
QListView::item:selected:!active {
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #ABAFE5, stop: 1 #8588B2);
}
QListView::item:selected:active {
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #6a6ea9, stop: 1 #888dd9);
}
QListView::item:hover {
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #FAFBFE, stop: 1 #DCDEF1);
}