您的位置:首页 > 编程语言 > Qt开发

QSS基础知识学习

2016-11-09 15:40 501 查看
这几天学习了下QSS空间的美化,以下是一些基础知识的总结!

建议QSS的使用步骤:
先在Designer里面写QSS,能实时的看到效果,满意后写到qss文件中

从文件中读取QSS复制给QString然后应用程序设置样式表,例如:

QFile file(":/sourceFile/styleSheet.qss");
file.open(QEODevice::ReadOnly | QIODevice::Text);
QString strStyleSheet(file.readAll());
app.setStyleSheet(strStyleSheet);


常用的设置:

QLabel {
/* 相当于 font: bold 50px "Snell Roundhand"; */
font-size: 50px;
font-weight: bold;
font-family: "Snell Roundhand";

color: white;

/* 相当于 background: lightgray url(:/resources/horizontal-add-line.png); */
background-color: lightgray;
background-image: url(:/resources/horizontal-add-line.png);

/* 相当于 border: 5px solid gray; */
border-width: 5px;
border-color: gray;
border-style: solid;
border-radius: 10px;
}
<pre name="code" class="cpp">设置字体常用:
font-style    <italic 斜体  oblique 倾斜 normal 正常>
font-size	 <设置字体的大小>
font-weight	 <设置字体的粗细 bold 相当于700左右>
font-family	 <设置字体的系列 如arial courier等>
color		 <字体颜色>

设置背景图片有以下设置:
background-color  			<背景颜色>
background-position			<位置>
background-repeat			<重复>
background-attachment		<拉伸、滚动>
background-image			<资源图片>

background-position可选值:
top left、top center、top right、
Center left、Center center、Center right、
bottom left、bottom center、bottom right
repeat可选值:
repeat-x <水平重复>	repeat-y<垂直重复>	no-repeat<不重复>
attachment可选值:
scroll  <背景随着滚动条滚动> 、fixed	<不滚动>

background-image中url 中的路径可以是:
资源文件的路径(:/ 开头)
绝对路径
相对于可执行文件的相对路径

设置边框常用:
border-width		<边框宽>
border-style		<边框样式 如 solid 实线等>
border-color		<颜色>
border-radius		<圆角>
border-image		<图片 如:url(":/image.png") 10 10 10 10 repeat stretch>
border-image参数说
url:资源文件路径
四个数字分别是:<注意这些数字并没有单位>
背景图片中 最上面 的10px高的图像填充到widget的border-top
背景图片中 最右边 的10px高的图像填充到widget的border-right
背景图片中 最下面 的10px高的图像填充到widget的border-bottom
背景图片中 最左边 的10px高的图像填充到widget的border-left
数字后的第一个参数 repeat|round|stretch 指定水平方向的缩放或平铺
数字后的第二个参数 repeat|round|stretch 指定垂直方向的缩放或平铺



盒子模型:

每个 Widget 所在的范围都是一个矩形区域(无规则窗口也是一个矩形,只是有的地方是透明的,看上去不是一个矩形而已),像是一个盒子一样。QSS 支持盒子模型(Box Model),和 CSS 的盒子模型是一样的,由 4 个部分组成:content, padding, border, margin,也就是说,Widget 的矩形区域,用这 4 个矩形表示



content
: 绘制内容的矩形区域(如绘制文本、图片),Qt 自带的 widget 都是在 content 区里绘制内容,这只是一个约定,只要你愿意,也可以在绘制到 padding, border, margin 区
padding
: 内容区和边框之间的间隔
border
: 边框,可视化的显示一个 widget 的逻辑范围,而不一定是 widget 所占矩形区域的实际大小
margin
: 想像 widget 的矩形区域有一个隐形的边框,margin 就是 border 和这个隐形边框之间的间

QSS选择器:

以下内容转载自:http://qtdebug.com/QSS-Selector.html
选择器决定了 style sheet 作用于哪些 Widget,QSS
支持 CSS2 定义的所有选择器

QSS 的选择器有:

通用选择器 *
类型选择器
类选择器
ID 选择器
属性选择器
包含选择器
子元素选择器
伪类选择器
Subcontrol 选择器

很多时候,可以使用不同的选择器实现相同效果的样式,使用非常灵活。

通用选择器 *

*
 作为选择器,作用于所有的 Widget。

类型选择器

类名
 作为选择器,作用于它自己和它的所有子类。

QFrame {
background: gray;
}

使用了类型选择器 
QFrame
,所以 QFrame 和它的子类 QLable,QLCDNumber,QTableWidget 等的背景会是灰色的,QPushButton 不是 QFrame 的子类,所以不受影响:



类选择器

. + 类名
 或者 
. + class 的属性值
 作为选择器,只会作用于它自己,它的子类不受影响。

#include <QApplication>
#include <QPushButton>
#include <QHBoxLayout>

int main(int argc, char *argv[]) {
QApplication app(argc, argv);

app.setStyleSheet("QWidget { background: gray; }");

QWidget *window = new QWidget();
QPushButton *openButton  = new QPushButton("打开", window);
QPushButton *closeButton = new QPushButton("关闭", window);
QPushButton *saveButton  = new QPushButton("保存", window);

QHBoxLayout *layout = new QHBoxLayout(window);
layout->addWidget(openButton);
layout->addWidget(closeButton);
layout->addWidget(saveButton);
window->setLayout(layout);
window->show();

return app.exec();
}

window, openButton, closeButton 和 saveButton 的背景都变成灰色的了,如果只想要 window 的背景是灰色的,按钮的背景不变,可以这么设置

/* 把 QWidget 改成 .QWidget */
app.setStyleSheet(".QWidget {background: gray;}")

如果 openButton 和 closeButton 的背景是洋红色的,但是 saveButton 不受影响,则可以使用 
. + class 的属性值
 作为类选择器来设置

app.setStyleSheet(".QWidget { background: gray; }"
".QPushButton[level='dangerous'] { background: magenta; }");

// .RedButton 将作为类选择器
openButton->setProperty("class", "RedButton");
closeButton->setProperty("class", "RedButton");




属性的值可以用单引号,双引号括起来,如果值没有空格,甚至可以不用引号,但不推荐这么做:
.QPushButton[level="dangerous"]

.QPushButton[level='dangerous']

.QPushButton[level=dangerous]

ID 选择器

# + objectName
 作为选择器,只作用于用此 objectName 的对象(多个对象可以使用同一个 objectName,但是不推荐这么做)。如上面的程序, openButton 和 closeButton 的背景是洋红色的,但是 saveButton 不受影响,也可以使用 
ID 选择器
来实现:

app.setStyleSheet(".QWidget { background: gray; }"
"#openButton, #closeButton { background: magenta; }");

// #openButton 和 #closeButton 作为 ID 选择器
openButton->setObjectName("openButton");
closeButton->setObjectName("closeButton");

属性选择器

选择器[属性="值"]
 作为选择器,这个属性可用通过 object->property(propertyName) 访问的,Qt 里称为 
Dynamic Properties


如上面的程序, openButton 和 closeButton 的背景是洋红色的,但是 saveButton 不受影响,也可以使用属性选择器 来实现:

app.setStyleSheet(".QWidget { background: gray; }"
"QPushButton[level=\"dangerous\"] { background: magenta; }");

openButton->setProperty("level", "dangerous");
closeButton->setProperty("level", "dangerous");

QSS 会把所有 QPushButton 中 level 属性值为 dangerous 按钮的背景绘制为洋红色,其他按钮的背景色不受这个 QSS 影响。

包含选择器

英语叫做 
Descendant Selector
,descendant 的表达比较到位。

选择器之间用空格隔开
,作用于 Widget 的 
子Widget
子Widget 的 子Widget
,……,子子孙孙,无穷尽也。

QFrame {
background: gray;
}

QFrame QPushButton {
border: 2px solid magenta;
border-radius: 10px;
background: white;
padding: 2px 15px;
}

顶部的 QPushButton 是 QFrame 的 descendant,所以 QSS 生效了,左下角的 QPushButton 的 parent 是 QWidget,所以 QSS 不起作用:



子元素选择器

选择器之间用 > 隔开
,作用于 Widget 的直接 
子Widget


QFrame {
background: gray;
}

QFrame > QPushButton {
border: 2px solid magenta;
border-radius: 10px;
background: white;
padding: 2px 15px;
}

按钮 
Child of QGroupBox
 的 parent 是 QGroupBox,QGroupBox 的 parent 是 QFrame,所以 
Child of QGroupBox
 虽然是 QFrame 的 
子Widget
 的 
子Widget
,但不是 QFrame 的直接 
子Widget
,故
QSS 不起作用,而 按钮 
Child of QFrame
 的 parent 是 QFrame,所以它的样式改变了:



伪类选择器

选择器:状态
 作为选择器,支持 
!
 操作符,表示 


QPushButton:hover { color: white }
QCheckBox:checked { color: white }
QCheckBox:!checked { color: red }

鼠标放到 QPushButton 上时,它的文字为白色,QCheckBox 选中时文字为白色,未选中时为红色。

伪类选择器还支持链式规则:
选择器:状态1:状态2:状态3
,状态之间使用逻辑与,同时满足条件样式才生效

QCheckBox:hover:checked { color: white }

鼠标 
放到
 
选中的
 QCheckBox 上时,它的字体为白色。

常用伪类选择器有:
伪类说明
:disabledWidget 被禁用时
:enabledWidget 可使用时
:focusWidget 得到输入焦点
:hover鼠标放到 Widget 上
:pressed鼠标按下时
:checked被选中时
:unchecked未选中时
:has-childrenItem 有子 item,例如 QTreeView 的 item 有子 item 时
:has-siblingsItem 有 兄弟,例如 QTreeView 的 item 有兄弟 item 时
:open打开或展开状态,例如 QTreeView 的 item 展开,QPushButton 的菜单弹出时
:closed关闭或者非展开状态
:onWidget 状态是可切换的(toggle), 在 on 状态
:offWidget 状态是可切换的(toggle), 在 off 状态
伪类的说明写成中文怎么感觉都很别扭,惭愧,表达能力欠佳,在此仅作为抛砖引玉吧,更多更详细的内容请参考 Qt 的帮助文档,搜索 
Qt Style Sheets Reference
,查看最下面的 
List of Pseudo-States


当然,这些伪类并不是对任何 Widget 都起作用,例如 QLabel 没有 :checked 状态,即使设置了样式 
QLabel:checked {color: red}
,对 QLabel 也是没有效果的,只有 Widget 支持某个状态,那么对应的伪类的样式才有作用。

Subcontrol 选择器

选择器::subcontrol
 作为选择 Subcontrol 的选择器。

有些 Widget 是由多个部分组合成的,例如 QCheckBox 由 icon(indicator) 和 text 组成,可以使用 
选择器::subcontrol
 来设置 subcontrol 的样式:

QCheckBox::indicator {
width: 20px;
height: 20px;
}
QCheckBox {
spacing: 8px;
}




常用的 Subcontrol 有:
Subcontrol说明
::indicatorA QCheckBox, QRadioButton, checkable QMenu item, 

or a checkable QGroupBox's indicator
::menu-indicatorA QPushButton's menu indicator
::itemA QMenu, QMenuBar, or QStatusBar's item
::up-buttonA QSpinBox or QScrollBar's up button
::down-buttonA QSpinBox or QScrollBar's down button
::up-arrowA QSpinBox, QScrollBar, or QHeaderView's up arrow
::down-arrowA QSpinBox, QScrollBar, or QHeaderView's down arrow
::drop-downA QComboBox's drop-down arrow
::titleA QGroupBox or QDockWidget's title
::grooveA QSlider's groove
::chunkA QProgressBar's progress chunk
::branchA QTreeView's branch indicator
更多更详细的内容请参考 Qt 的帮助文档,搜索 
Qt Style Sheets Reference
,查看最下面的 
List of Sub-Controls



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息