内容来自https://www.cnblogs.com/linuxAndMcu/p/11039691.html,我把他3篇整成一篇了。
=====================Qt样式表之一:Qt样式表和盒子模型介绍=====================
一、Qt样式表介绍
Qt样式表是一个可以自定义部件外观的十分强大的机制,可以用来美化部件。Qt样式表的概念、术语和语法都受到了HTML的层叠样式表(Cascading Style Sheets, CSS)的启发,不过与CSS不同的是,Qt样式表应用于部件的世界。
二、使用代码设置样式表
样式表使用文本描述,可以使用 QApplication:: setStyleSheet() 函数将其设置到整个应用程序上,也可以使用 QWidget::setStyleSheet() 函数将其设置到一个指定的部件(还有它的子部件)上。如果在不同的级别都设置了样式表,那么Qt会使用所有有效的样式表,这被称为样式表的层叠。下面来看一个简单的例子。
新建Qt Gui应用,项目名称为myStyleSheets,类名为MainWindow,基类保持QMainWindow不变。建立好项目后进入设计模式,向界面上拖入一个PushButton和一个Horizontal Slider,然后在mainwindow.cpp文件中的构造函数里添加如下代码:
//设置pushButton的背景颜色为黄色
ui->pushButton->setStyleSheet("background:yellow");
//设置horizontalSlider的背贵为蓝色
ui->horizontalSlider->setStyleSheet("background:blue");
这样便设置了两个部件的背景色。不过像这样调用指定部件的setStyleSheet()函数只会对这个部件应用该样式表,如果想对所有的相同部件都使用相同的样式表,那么可以在它们的父部件上设置样式表。因为这里两个部件都在MainWindow上,所以可以为MainWindow设置样式表。先注释掉上面的两行代码,然后添加如下代码:
this->setStyleSheet("background:blue");
这样,以后再往主窗口上添加的所有QPushButton部件和QSlider部件的背景色都会改为这里指定的颜色。
三、在设计模式中设置样式表
除了使用代码来设置样式表外,也可以在设计模式中为添加到界面上的部件设置样式表,这样更加直观。先注释掉上面添加的代码,然后进入设计模式。在界面上右击,在弹出的菜单中选择“改变样式表”,这时会出现编辑样式表对话框,在其中输入如下代码:
QPushButton{
}
注意光标留在第一个大括号后。然后单击上面“添加颜色”选项后面的下拉箭头, 在弹出的列表中选择“background-color”一项。这时会弹出选择颜色对话框,随便选择一个颜色,然后单击“确定按钮”,这时会自动添加代码:
QPushButton{
background-color: rgb(0, 0, 255);
}
可以看到,在这里设置样式表不仅很便捷而且很直观,不仅可以设置颜色,还可以使用图片,使用渐变颜色或者更改字体。在设计模式,有时无法正常显示设置好的样式表效果,不过运行程序后会正常显示的。这里是在MainWindow界面上设置了样式表,当然,也可以按照这种方法在指定的部件上添加样式表。
四、盒子模型介绍
使用Style Sheets时,所有的部件都被视为有四个同心矩形的盒子(box):边缘矩形(margin rectangle),边框矩形(border rectangle),填充矩形(padding rectangle)和内容矩形(content rectangle)。盒子模型对四个矩形有详细的描述,如下图所示:
边缘,边框宽度和填充属性默认为0。这样四个矩形(margin, border, padding和content)重合。
使用background-image属性,你可以为部件指定背景图片。默认地,背景图片只画在边框以内。背景图片不随部件大小改变而改变。提供一个随部件大小改变而改变的背景或皮肤,必须使用border-image。因为border-image属性提供了一个备选背景,所以并不需要再为部件指定一个背景图片。在两者都指定的情况下,border-image将画于background-image之上。
=====================Qt样式表之二:QSS语法及常用样式=====================
Qt样式表(以下统称QSS)的术语和语法规则几乎和CSS相同。如果你熟悉CSS,可以快速浏览以下内容。不熟悉的话可以先去W3School - CSS或者本人的CSS博客随笔简单了解一下。
在讲解样式表语法前,我们先看一个例子:
/*按钮普通态*/QPushButton{ /*字体为微软雅黑*/ font-family:Microsoft Yahei; /*字体大小为20点*/ font-size:20pt; /*字体颜色为白色*/ color:white; /*背景颜色*/ background-color:rgb(14 , 150 , 254); /*边框圆角半径为8像素*/ border-radius:8px; }/*按钮停留态*/QPushButton:hover{ /*背景颜色*/ background-color:rgb(44 , 137 , 255); }/*按钮按下态*/QPushButton:pressed{ /*背景颜色*/ background-color:rgb(14 , 135 , 228); /*左内边距为3像素,让按下时字向右移动3像素*/ padding-left:3px; /*上内边距为3像素,让按下时字向下移动3像素*/ padding-top:3px; }
上面例子是实现按钮三态效果的样式表。
注:程序设置的样式表比ui文件里设置的优先级更高。
QSS包含了一个样式规则,一个样式规则由一个选择器和声明组成,选择器指定哪些部件由规则影响,声明指定哪些属性应该在部件上进行设置。例如:
QPushButton { color: red }
上面的例子中QPushButton是选择器,是声明,该规则指定QPushButton及其子类(例如:MyPushButton)应使用红色作为前景色。
几个选择器可以指定相同的声明,使用逗号(,)来分隔选择器。例如:
QPushButton, QLineEdit, QComboBox { color: red }
相当于三个规则序列:
QPushButton { color: red }QLineEdit { color: red }QComboBox { color: red }
声明部分的规则是一个属性值对(property: value)列表,包含在花括号中,以分号分隔。例如:
QPushButton { color: red; background-color: white }
参考助手:Qt Style Sheets Reference
中List of Properties
部分。
注:QSS通常不区分大小写(即:color、Color、COLOR、cOloR指同一属性),唯一例外就是类名(class names)、对象名(object names)、属性名(property names)区分大小写。
下表总结了最有用的选择器,所有示例使用了选择器中最简单的类型,类型选择器QSS支持所有的selectors defined in CSS2。
选择器 | 示例 | 说明 |
---|---|---|
通用选择器 | * | 匹配所有部件 |
类型选择器 | QPushButton | 匹配QPushButton及其子类的实例 |
属性选择器 | QPushButton[flat="false"] | 匹配QPushButton中flat属性为false的实例。 |
类选择器 | .QPushButton | 匹配QPushButton的实例,但不包含子类。相当于*[class~=” QPushButton”]。 |
ID选择器 | QPushButton#okButton | 匹配所有objectName为okButton的QPushButton实例。 |
后代选择器 | QDialog QPushButton | 匹配属于QDialog后代(孩子,孙子等)的QPushButton所有实例。 |
子选择器 | QDialog > QPushButton | 匹配属于QDialog直接子类的QPushButton所有实例。 |
还可以这样,比如某个特定窗口的名字为mywidget,那么他内部的按钮这样设置:
#mywidget QPushButton,如果要具体到某个按钮,继续增加即可:
#mywidget QPushButton#mybutton
注意:#不能有空格
对于样式复杂的部件,需要访问子控件,例如:QComboBox的下拉按钮或QSpinBox的上下箭头。选择器可能包含子控件,使得可以限制特有部件子控件的应用规则。例如:
QComboBox::drop-down { image: url(dropdown.png) }
上述规则指定了QComboBoxe下拉按钮样式,虽然双冒号(::)语法让人想起CSS3伪元素,但Qt子控件从概念上讲有不同的级联语义。
子控件定位总是相对于另一个参考元素,这个参考元素可能是小部件或其它子控件。例如:QComboBox的drop-down放置,默认的放置在QComboBox区域的右上角。而drop-down放置,默认的在::drop-down子控件的中央。
width和height属性可用于控制子控件的大小,注意:设置一个图片会隐式地设置子控件的大小。相对定位(position : relative):可以改变子控件相对初始位置的偏移量。例如:按下QComboBox下拉按钮时,我们可能更喜欢用内部箭头偏移量来产生一个被按下的效果。要做到这一点,我们可以指定:
QComboBox::down-arrow { image: url(down_arrow.png); }QComboBox::down-arrow:pressed { position: relative; top: 1px; left: 1px; }
绝对定位(position : absolute):允许子控件改变位置和的大小而不受参考元素限制。
参考助手:Qt Style Sheets Reference
中List of Sub-Controls
部分,及Qt Style Sheets Examples
中Customizing the QPushButton's Menu Indicator Sub-Control
部分。
选择器可以包含伪状态,意味着限制基于部件状态的应用程序规则。伪状态出现在选择器后面,用冒号(:)关联。例如,鼠标划过按钮:
QPushButton:hover { color: white }
伪状态可以用感叹号(!)运算符表示否定。例如,当鼠标不划过QRadioButton:
QRadioButton:!hover { color: red }
伪状态可以连接使用,这种情况下,相当于隐含了一个逻辑与。例如,当鼠标滑过选中的QCheckBox:
QCheckBox:hover:checked { color: white }
否定的伪状态也可以连接使用,例如,当鼠标划过一个非按下时按钮:
QPushButton:hover:!pressed { color: blue; }
如果需要,也可以使用逗号操作来表示逻辑或:
QCheckBox:hover, QCheckBox:checked { color: white }
伪状态也可以与子控件组合,例如:
QComboBox::drop-down:hover { image: url(dropdown_bright.png) }
参见助手:Qt Style Sheets Reference
中List of Pseudo-States
部分。
示例一
当样式中指定相同的属性具有不同的值时,就会出现冲突。例如:
QPushButton#okButton { color: blue }QPushButton { color: red }
要解决这个冲突,必须考虑到的选择器的特殊性。上面的例子,QPushButton#okButton 被认为比 QPushButton 更具体,因为它通常是指单个对象,而不是一类的所有实例。所以 okButton 这个按钮文本颜色会设置为blue,而其它按钮文本仍然设置为red。
示例二
同样的,利用伪状态比不指定伪状态那些选择器更具体。因此,下面的样式指定一个QPushButton应该有鼠标悬停文本颜色为白色,否则文本颜色为红色。
QPushButton:hover { color: white }QPushButton { color: red }
示例三
QPushButton:hover { color: white }QPushButton:enabled { color: red }
这里,两个选择器有相同的特殊性,但后一条规则优先,即QPushButton:enabled { color: red }
优先级更高,所以按钮默认 enabled 的情况下,无论鼠标是否悬停在按钮上,文本颜色始终为白色。
QPushButton:enabled { color: red }QPushButton:hover { color: white }
想要鼠标是否悬停在按钮上文本颜色为白色,根据后面规则优先级更高的原则,则使颜色为white的规则在后面即可,如上所示。
或者,可以使文本颜色为白色的规则更加具体:
QPushButton:hover:enabled { color: white }QPushButton:enabled { color: red }
示例四
类似的问题出现在类型选择器一起使用。请看下面的例子:
QPushButton { color: red }QAbstractButton { color: blue }
两个规则应用于 QPushButton 实例(因为 QPushButton 继承自 QAbstractButton)并有color属性的冲突。因为 QPushButton 继承 QAbstractButton,所以 QPushButton 比 QAbstractButton 更具体,本应该按钮文本颜色为红色。然而,对于QSS的计算,所有的类型选择具有相同的特殊性,最后出现的规则优先,所以实际上按钮文本颜色为蓝色。如果需要设置QPushButtons为红色文字,需要重新排序规则。
总结
为了确定一个规则的特殊性,QSS遵循CSS2规范,一个选择器的特殊性的计算方法如下:
计算选择器中ID属性的数量(= a)
计算选择器中伪状态类和其它属性的数量(= b)
计算选择器中元素名的数量(= c)
忽略伪元素(即子控件)。
串联的三个数字a-b-c(在具有大基数的数字系统)给出的特殊性。一些例子如下:
* {} /* a=0 b=0 c=0 -> specificity = 0 */ LI {} /* a=0 b=0 c=1 -> specificity = 1 */ UL LI {} /* a=0 b=0 c=2 -> specificity = 2 */ UL OL+LI {} /* a=0 b=0 c=3 -> specificity = 3 */ H1 + *[REL=up] {} /* a=0 b=1 c=1 -> specificity = 11 */ UL OL LI.color {} /* a=0 b=1 c=3 -> specificity = 13 */ LI.color.width {} /* a=0 b=2 c=1 -> specificity = 21 */ #okButton {} /* a=1 b=0 c=0 -> specificity = 100 */
QSS可以在QApplication、父部件、子部件中设置。冲突发生时,不论冲突规则的特殊性,部件自身的样式表总优先于任何继承样式表。考虑下面的例子。首先,我们在QApplication中设置样式表:
qApp->setStyleSheet("QPushButton { color: white }");
然后,我们设置QPushButton的样式表:
myPushButton->setStyleSheet("color: blue");
QPushButton样式表强制QPushButton(以及任何子部件)显示蓝色文字,尽管应用程序范围内的样式表提供的规则更具体。
在经典的CSS中,当字体和颜色没有明确设置时,它就会自动从父继承。当使用QSS时,部件不会自动从父继承字体和颜色。例如,一个QGroupBox中包含QPushButton:
qApp->setStyleSheet("QGroupBox { color: red; } ");
QPushButton不会继承其父QGroupBox的颜色,而是显示系统的颜色。
CSS文字属性及示例 | 说明 |
---|---|
color:#999999; | 文字颜色 |
font-family:Microsoft Yahei,sans-serif; | 字体家族 |
font-size:16pt; | 字体大小 |
font-style:itelic;(normal、oblique) | 字体样式 |
letter-spacing:1pt; | 字间距离 |
line-height:200%; | 设置行高 |
font-weight:bold;(lighter、normal、数值900) | 字体粗细 |
text-decoration:underline;(line-through、overline、none) | 字体修饰 |
text-align:left;(right、center、justify) | 文字左对齐 |
vertical-align:top;(bottom、middle、text-top、text-bottom) | 垂直对齐方式 |
text-transform:uppercase;(lowercase、capitalize) | 英文大写 |
font-variant: small-caps;(normal) | 小型大写字母 |
CSS背景样式及示例 | 说明 |
---|---|
background:black; | 背景颜色为黑色 |
background-color:#F5E2EC; | 背景颜色 |
background-image:url(/image/bg.gif); | 背景图片 |
background:transparent; | 透视背景 |
background-repeat : repeat; | 重复排列-网页默认 |
background-position : center; | 指定背景位置-居中对齐 |
CSS边框空白及示例 | 说明 |
---|---|
padding:5px 10px 5px 10px; | 所有边框留空白 |
padding-top:10px; | 上边框留空白 |
padding-right:10px; | 右边框留空白 |
padding-bottom:10px; | 下边框留空白 |
padding-left:10px; | 左边框留空白 |
CSS框线建议书写方式 | 说明 |
---|---|
border:1px solid red; | 所有边框线 |
border-top:1px solid #6699cc; | 上框线 |
border-bottom:1px solid #6699cc; | 下框线 |
border-left:1px solid #6699cc; | 左框线 |
border-right:1px solid #6699cc; | 右框线 |
border-radius:8px; | 边框圆角半径 |
以上是建议书写方式,但也可以使用常规书写方式,如下表所示:
CSS框线常规书写方式 | 说明 |
---|---|
border-top-color:#369; | 设置上框线颜色 |
border-top-width:1px; | 设置上框线宽度 |
border-top-style:solid | 设置上框线样式 |
其他框线样式如下:
solid - 实线
dotted - 虚线
double - 双线
inset - 凹框
outset - 凸框
groove - 立体内凸框
ridge - 立体浮雕框
CSS边界样式及示例 | 说明 |
---|---|
margin-top:10px; | 上边界值 |
margin-right:10px; | 右边界值 |
margin-bottom:10px; | 下边界值 |
margin-left:10px; | 左边界值 |
注:px:相对长度单位,像素(Pixel)。pt:绝对长度单位,点(Point)。
=====================Qt样式表之三:实现按钮三态效果的三种方法 =====================
按钮的三态,指的是普通态、鼠标的悬停态、按下态。Qt中如果使用的是默认按钮,三态的效果是有的,鼠标放上去会变色,点击的时候有凹陷的效果。
但是如果自定义按钮实现三态效果有三种方法,一种是设置背景图,主要是需要自己设计按钮的效果图,另一种是通过样式控制不同状态下按钮的显示效果,还有一种是通过qss文件实现。
先使用PS或其他图片工具设计按钮的背景图,然后在工程里添加背景图,将下面两张图片添加进去,具体过程这里不再介绍。
下面是普通态的背景图,用了同一张背景图(ok.png):
下面是悬停态的背景图(ok1.png):
下面是按下态的背景图(ok2.png):
样式表设置背景图可以使用setStyleSheet
函数,在程序里设置按钮的样式表,具体程序如下所示:
ui->pbut_boardimg_reset->setStyleSheet("QPushButton{border-image: url(:/new/prefix1/image/showmodeimag/ok.png);}" "QPushButton:hover{border-image: url(:/new/prefix1/image/showmodeimag/ok.png);}" "QPushButton:pressed{border-image: url(:/new/prefix1/image/showmodeimag/ok1.png);}");
也可以在 QtDesigner 上,即ui文件上的按钮处编辑样式表,如下图所示:
样式表如下:
QPushButton{border-image: url(:/new/prefix1/image/showmodeimag/ok.png)} QPushButton:hover{border-image: url(:/new/prefix1/image/showmodeimag/ok.png)} QPushButton:pressed{border-image: url(:/new/prefix1/image/showmodeimag/ok1.png)}
/*按钮普通态*/QPushButton { /*字体为微软雅黑*/ font-family:Microsoft Yahei; /*字体大小为20点*/ font-size:20pt; /*字体颜色为白色*/ color:white; /*背景颜色*/ background-color:rgb(14 , 150 , 254); /*边框圆角半径为8像素*/ border-radius:8px; }/*按钮停留态*/QPushButton:hover { /*背景颜色*/ background-color:rgb(44 , 137 , 255); }/*按钮按下态*/QPushButton:pressed { /*背景颜色*/ background-color:rgb(14 , 135 , 228); /*左内边距为3像素,让按下时字向右移动3像素*/ padding-left:3px; /*上内边距为3像素,让按下时字向下移动3像素*/ padding-top:3px; }
注:注释只能使用/* */
,#
和//
均无效。
可以看上图中“确定按钮”的三态效果。在鼠标悬停时背景色加深,按下时设置了padding,给人一种按钮被按下的感觉。
这种方法比上面用图标作为背景的好处就是可以不需要设计背景图,而且在样式不设置字体的情况下,可以随意更改文字以及文字的大小、位置、字体等显示效果。
新建一个txt文本文档,并修改后缀名为.qss,文件名任取,例如:myStyleSheet.qss,在这个qss文件写入qss语句。内容如下:
/*按钮普通态*/QPushButton { /*字体为微软雅黑*/ font-family:Microsoft Yahei; /*字体大小为20点*/ font-size:20pt; /*字体颜色为白色*/ color:white; /*背景颜色*/ background-color:rgb(14 , 150 , 254); /*边框圆角半径为8像素*/ border-radius:8px; }/*按钮停留态*/QPushButton:hover { /*背景颜色*/ background-color:rgb(44 , 137 , 255); }/*按钮按下态*/QPushButton:pressed { /*背景颜色*/ background-color:rgb(14 , 135 , 228); /*左内边距为3像素,让按下时字向右移动3像素*/ padding-left:3px; /*上内边距为3像素,让按下时字向下移动3像素*/ padding-top:3px; }
引用qss文件有两种方式,一是引用qss文件的外部路径,二是引用qss文件的资源路径。
一、引用qss文件的外部路径
加载qss文件时,需要指定文件路径(一般是相对路径),如果把qss文件放在磁盘上,文件暴露在用户眼皮底下,可能会被用户随意修改,解决方法就是把qss文件作为资源,一起打包进exe文件中。
二、引用qss文件的资源路径
步骤如下:
1、在qt左侧目录树的顶层文件夹上右击 -> 添加新文件 -> 选择QT -> QT resource file - > choose,输入自定义资源文件的名字 resource -> 选择资源文件的存放路径->下一步->ok,这样就可以在目录树中看到一个文件 resource.qrc。(如果已经创建过资源文件,则跳过该步)
2、右击 resource.qrc文件 -> open in editor,在打开的资源编辑器中,点击添加 -> 前缀 -> 修改前缀为 /qss, 再点击添加 -> 添加现有文件 -> 添加上选中我们上面做好的qss文件。完成后效果如下图所示。
3、写程序时需要读取该文件时,右击这个qss文件,选择复制url,即可复制本文件的资源路径。
//这是在Qt的资源下的文件,可以不用在资源下 QFile file(":/qss/myStyleSheet.qss"); //只读方式打开文件 file.open(QFile::ReadOnly); //读取文件的所有内容,并转换成QString类型 QString styleSheet = tr(file.readAll()); //当前窗口设置样式表 //this->setStyleSheet(styleSheet); //指定按钮设置样式表 ui->pushButton->setStyleSheet(styleSheet); ui->pushButton_2->setStyleSheet(styleSheet);
如果想设置单个的指定按钮样式,则通过UI指向按钮进行修改样式表就可以了。
上面的只设置了背景,那么怎么设置到按钮的左边或者右边呢?
重点来了,就是通过qproperty来搞:
QPushButton{ /*image: url(:/user.ico) ; image-position:0px left;*/ qproperty-icon: url(:/user.ico) off, url(:/user.ico) on; qproperty-iconSize: 16px 16px; }
优点 :样式简单,直接设置border-image即可,可以选取漂亮的UI图片,总体上可能会比单纯通过样式设置显示效果要好一些。(如果UI图选取效果不好的情况下,效果可能没有单纯设置样式好看,这就要看个人的审美观了哈O(∩_∩)O!)
缺点 :需要自己制定背景效果图, 可能比较耗时。
优点:不需要准备背景图,直接通过样式设置,简单、粗暴,想怎么设置就怎么设置(前提是要会一点CSS),能够更好地控制显示效果(比如控制文字的大小,位置、字体等)。
缺点:样式稍微复杂,需要懂更多的CSS样式,如果需要在按钮上加图标什么的就必须要加载背景图片了,单纯靠样式解决不了。
以上总结了两种方法的优缺点,可以说这两种方法可以相互取长补短,基本上运用好这两种方式就能够做出精美的按钮了,具体采样哪种方式就看自己如何选择了哈 O(∩_∩)O!
QPushButton{border-image: url(:/new/prefix1/image/showmodeimag/ok.png)}
如果我们使用如上样式,将会对所有的QPushButton进行设置样式,如果只需要给某一个则用以下格式:
“QPushButton#” + “按钮名称(objectName)”。
或者直接 #+objectName{}这样,例如#mybutton{}