文章目录
❤️一.前言
不少人应该和我同样,想作界面才接触的Qt,结果就是作不出来华丽的界面,想给控件上个色?不会,百度半天,好不容易给控件添加了背景色,下一个控件又不会了,别急,此次福利来了,我将平时用到的样式表作了一个总结,并作了一个一键生成,调节数据就能够实时显示,里面包括了Label,LineEdit,PushButton,CheckBox,RadioButton,ScrollBar,Slider,Progressbar,Tabwidget,ToolBox,TabWidget控件的自定义。代码很简单,就是重复写槽函数,但其对于新手的学习颇有帮助,避免了盲目,大量的经过百度数据拼接样式表。一来方便学习,因此参数都写在左下角,方便了解到使用了什么生成了什么,二来不用重复造轮子,调节后,可直接将左下角生成的QSS代码复制到qt的样式表里面便可显示效果。可能有一些人会说这是一种偷懒,让人逐渐不想学习,只能说智者见智仁者见仁吧。
css
而后上面是效果图,哈哈哈,你们若是想要软件,可直接拉到文末地址获取,而这篇文章除了想告诉你们这个一键生成以外,就是凑个字数好上推荐,哈哈,开个玩笑,仍是想主要说一下qt里面样式表的一个语法和使用步骤,以及一些经验。随着深刻学习,你会渐渐知道阅读文档和本身动手实践才是最高效的学习方法。html
❤️二.三种方式添加样式表
- 直接在Qt Designer 中添加样式
- 在代码中使用setstylesheet函数添加样式
- 建立qss文件添加样式
不管哪种添加,都离不开样式表语法,样式表语法由选择器和声明构成,选择器能够指定对谁生效,能够指定不一样状态时生效不一样的样式,而声明就是样式,这些知识点,下面都将一一说明。git
➡️1.先说第一种,直接在Qt Designer 中添加样式。
这种方式的优势就是快,直接,缺点也很明显,就是只能设定一次,应用在固定不变的ui上,这种方法是首选,可是当须要根据当前操做作出对应的变化,第一种方法就不行了,例如按一下按钮变一种颜色,或者调节参数,这时咱们就须要第二种方法。
github
➡️2.在代码中使用setstylesheet函数添加样式
好比在Qt Designer 上咱们拖了一个标签控件,咱们就能够在cpp这样来设置样式表:windows
ui->Lable->setStyleSheet("background:rgb(150, 190, 60);"); //注意后面的分号要加上,其实就是把第一种方法里面的样式表,加上双引号放在括号里面就能够了。
利用第二种方法就能够随意更改样式表:编辑器
if(xxxx) { ui->Lable->setStyleSheet("background:rgb(150, 190, 60);"); } if(xxxx) { ui->Lable->setStyleSheet("background:rgb(150, 100, 100);"); }
第二种方法也有缺点,就是耦合性高,为了下降耦合性(与逻辑代码分离),咱们一般会定义一个QSS文件,来存放样式,也就是第三种方式。ide
注意:setStyleSheet的设置以最后一次设置为准,每次设置(调用setStyleSheet(“样式”))都会覆盖以前一次设置的样式。
函数
➡️3.建立qss文件添加样式
建立qss文件不要使用windows下的记事本,这里推荐使用Nodetad++或者更高级的编辑器。不然可能会出错。
缘由是记事本生成的utf-8文件是带bom(自行百度),这个咱们没法经过记事本去掉,而Nodetad++能够,尽管qt在编码项目-编码有一个老是bom的选项,可是经测试,没什么用,bom仍是存在,能够看一下这个Qt读取qss文件失败或qss不生效解决方案。
咱们建立一个qss后缀的文件,并写入
学习
#label { background:rgb(100,100,100); }
将这个qss文件做为资源文件加载到qt中,以下图,建立一个资源文件,并添加现有文件(qss文件):
在构造函数中编写以下代码:
测试
QString qss; QFile qssFile("./lib/sheet.qss"); qssFile.open(QFile::ReadOnly); if(qssFile.isOpen()) { qss=QLatin1String(qssFile.readAll()); qDebug()<<qss; this->setStyleSheet(qss); qssFile.close(); }
最后将utf-8 bom由原先的是utf-8就添加改成目前存在了则保留。至此qss样式表加载完成。
运行结果:
这就是第三方法,这种方法在界面样式较复杂时,咱们在文件中编写样式,内容比较清晰,下降耦合性(与逻辑代码分离)。
- 三种方法使用哪种?
- 对于初学者,我认为第一种方法是首选,由于初学者每每不须要过多复杂控件,对于少许的控件,代码也不是不少,使用第一种方法简单高效,而且能够帮助咱们检验样式是否编写正确,这是对于初学者最有帮助。
- 对于有一点基础的,随着学习的深刻,不用我说,也应该感受到第一种的局限性,也就是我说是的缺点,这个时候就应该使用第二种方法,来弥补第一种方法带来的缺陷,这个时候控件还不是不少,代码写样式表还容易找。
- 第三种方法就是对于你已经很厉害了,能写出一个本身看得过去的程序了,控件也多了起来,业务逻辑也多了起来,这个时候就能够下降耦合性(与逻辑代码分离),从而使用第三方法。
- 最终的建议就是说将第二种和第三者方法结合使用,来弥补各自的不足。
为了讲解方便,下面的说明将使用第一种方法展开。
❤️三.选择器
qt的官方文档介绍了最有的选择器,而不是最全的,Qt样式表支持CSS2中定义的全部选择器。下面截取了qt支持的选择器,点击浏览CSS2文档。
翻译过来就是,使用的网页翻译,可能有错误。
想要所有介绍,我以为不现实,因此就拿一些经常使用的来举例子,各位看官触类旁通。
➡️1.通用选择器(*)
通用选择器能够说是最老实的选择器,它匹配因此的控件。若是通用选择器不是"简单选择器"的惟一组成部分,则能够省略“ *”。好比
*#label { background-color:rgb(50,50,50);//声明 }
选择器中除了通用选择器,还有咱们下面将要介绍的ID选择器,注意上面那句话:若是通用选择器不是"简单选择器"的惟一组成部分,则能够省略“ *”。因此这里的“*”是能够省略的。
#label { background-color:rgb(50,50,50);//声明 }
所达到的效果和上面的效果是同样的。因此也是最简单的选择器。
➡️2.类型选择器(控件类名,如QPushButton)
类型选择器会匹配控件类及其子类的实例,与类选择器的不一样的是类选择器匹配控件类实例,但不匹配其子类的实例。
QPushBuuton { background-color: rgb(0, 255, 255); }
当有多个相同控件,例如按钮须要使用一种样式表的时候,就可使用类型选择器,咱们只须要将按钮放在同一个容器中,例如frame,就能够应用到容器中的按钮了,点击Apply,糟糕,是否是没有任何做用?不急,让咱们看看文档怎么说。
在按钮控件旁边的说明中,有一个警告,翻译过来就是:
警告:若是仅在QPushButton上设置背景色,除非将border属性设置为某个值,不然背景可能不会出现。这是由于,默认状况下,QPushButton绘制的本机边框与背景色彻底重叠。
哦,咱们知道了想要让背景生效,就须要指定border这个值,那咱们就随便给border加一个值,再点击Apply看看,是否是好了。
➡️3.后代选择器(QFrame QPushBuuton)
QFrame QPushBuuton { background-color: rgb(0, 255, 255); border:none; }
匹配全部QPushButton实例,它们是QFrame的后代(子代,孙子代等),如图中的QFrame(蓝色)中包含了四个QPushButton,以及一个QWidget(黄色),而且QWidget下面还有两个QPushButton,这样对于QFrame来讲,四个QPushButton和QWidget是子代,而QWidget里面的两个QPushButton对于QFrame来讲就是孙子代。
➡️4.子代选择器(QFrame > QPushBuuton)
QFrame > QPushBuuton { background-color: rgb(0, 255, 255); border:none; }
匹配全部QPushButton实例,它们是QFrame的直接子代,仍是拿上面的图来体现,QFrame QPushBuuton中间加了>符号之后,只有QFrame的直接子代能够匹配。
➡️5.ID选择器(QLabel #label)
匹配对象名称为label的全部QLabel实例。
这里的QLabel和通用选择器一个,能够选择省略,由于每一个控件的ID(名字)是同样的,无需指定类型,这个没什么难点。
➡️6.类选择器(.QPushButton)
.QPushBuuton
{
background-color: rgb(0, 255, 255);
border:none;
}
匹配QPushButton的实例,但不匹配其子类的实例,这个能够说与类型选择器是一对,就好像后代选择器和子代选择器的关系,这种选择器只会匹配该类的全部对象, 而不会匹配其派生类的对象。
➡️7.属性选择器(QPushButton[flat=“false”])
属性选择器应用于同一个类型下不一样实现效果(如但愿 QPushButton 有两套通用样式),文字好理解,操做起来不必定好理解,我举两个例子帮助你们理解。
QPushButton { color:rgb(100,0,0); border:none; } QPushButton[flat = "true"] { background-color:rgb(100,100,100); } QPushButton[flat = "false"] { background-color:rgb(255,255,255); }
flat=“false”/flat=“true”这两个值,能够随意定义,格式就是“key”对应“value”。(随便说一下这个flat属性,为真的时候就是去掉边框,鼠标按下去才会出现边框,能够提示用户体验。)定义类型属性,须要用到setProperty(“key”,“value”);这个函数,咱们来试一下,先建立两个按钮,而后用咱们上面说过的第二种样式表添加方法来实现。
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); ui->pushButton_3->setProperty("name","zhangsan"); ui->pushButton_4->setProperty("name","lisi"); this->setStyleSheet("QPushButton{color:rgb(255,255,255);}" "QPushButton[name = 'zhangsan']{background:rgb(0,0,255);}" "QPushButton[name = \"lisi\"]{background:rgb(255,0,0);}"); //这里的value 用双引号或者单引号均可以 }
效果以下:
❤️四.伪类
➡️1.状态伪类
伪状态对类型选择器或类选择器指定的全部控件设置它在指定状态时的样式,伪状态以冒号(:)做为分隔 紧跟着选择器,状态伪类不少,上图是从官方截取的,全部的伪状态,都打包进了软件,你们能够下载软件查看,这里就介绍两个初学者经常使用的,让你们体会到伪状态的用法。
可能细心读者已经发现了,至此,咱们上面所说的这些样式是固定样式,通俗一点就是不会动,为了能给用户更好的体验和互交,软件界面的按钮或者什么功能控件,当鼠标滑过或者按下去,控件自己就会发送变化,伪状态就是运用到了这里,咱们一块儿往下看。
#pushButton_4 { background-color: rgb(78, 110, 255); border:none; } #pushButton_4:hover { background-color: rgb(255, 80, 141); }
这个:hover就是伪状态,表示鼠标滑过期的样式。
:pressed 鼠标按下
这里咱们不光能指定颜色,也能够指定文字的颜色,大小,字体,都是能够的。
:focus 焦点,这个多用于文本输入框。
软件包含大量伪状态说明,可下载查看。
❤️五.声明
声明就是{}号里面的内容,例如:
- background:rgb(150, 190, 60); 背景颜色
- border-color:rgba(0,0,0,255); 边框颜色
- color:rgb(150, 190, 60);文字颜色
- border-style:none; 边框风格
- border-radius:0px;圆角大小
- font:15px “宋体”;字体大小/字体
- font-weight: bold;字体粗细
- text-decoration:line-through;字体修饰
更多的可使用软件查看:里面包含了大量声明。包括文末最后的官方连接。
❤️六.子控件
除了像QLabel,QPushButton这一类比较简单的控件,没有子控件,还有复杂控件,他们除了自己,还有属于本身的子控件。
为何复杂控件须要子控件呢,好比Slider滑条:
- 滑块(红色)的凹槽使用:: groove设置样式。默认状况下,凹槽位于窗口小部件的“内容”矩形中。
- 滑块(绿色)的拇指使用:: handle子控件设置样式。子控件在凹槽子控件的“内容”矩形中移动。
若是只是简单控件,那么一旦设置背景颜色,整个滑块和滑块的拇指都是一个颜色,显然对用户不太友好,而将两个简单控件组成复杂控件,这样就能够单独对某一个小控件进行样式调整,大大提示美感。
关于全部的子控件,你们能够点击文末地址,也可使用软件。
❤️七.解决冲突
当多个样式规则使用不一样的值指定相同的属性时,就会发生冲突。考虑如下样式表:
QPushButton #okButton {color: gray} QPushButton {color: red}
这两个规则都匹配被调用的QPushButton实例okButton,而且该color属性存在冲突。要解决此冲突,咱们必须考虑选择器的特殊性。在上面的示例中,QPushButton#okButton被认为比更为具体QPushButton,由于它(一般)引用单个对象,而不是类的全部实例。
一样,具备伪状态的选择器比未指定伪状态的选择器更具体。所以,如下样式表指定当鼠标悬停在QPushButton上时,QPushButton应该具备白色文本,而不是红色文本:
QPushButton:hover { color: white } QPushButton { color: red }
为了肯定规则的特殊性,Qt样式表遵循CSS2规范:
选择器的特异性计算以下:
计算选择器中ID属性的数量(= a)
计算选择器中其余属性和伪类的数量(= b)
计算选择器中元素名称的数量(= c)
忽略伪元素[即子控件 ]。
将三个数字abc(在基数较大的数字系统中)链接起来可得出特异性。
一些例子:
获得的数字最大者即最终样式,若是数字同样,则以最后样式表为准。
❤️八.级联和遗产
➡️1.级联
能够在QApplication父窗口小部件和子窗口小部件上设置样式表。经过合并在小部件祖先(父母,祖父母等)上设置的样式表以及在QApplication上设置的任何样式表,能够获取任意小部件的有效样式表。
当发生冲突时,不管冲突规则的特殊性如何,始终要优先于任何继承的样式表使用窗口小部件本身的样式表。一样,父窗口小部件的样式表优先于祖父母的样式表等。
这样的结果之一是,在窗口小部件上设置样式规则会自动赋予它优先于祖先窗口小部件的样式表或QApplication样式表中指定的其余规则的优先级。考虑如下示例。首先,咱们在QApplication上设置样式表:
qApp->setStyleSheet("QPushButton { color: white }");
而后,在QPushButton对象上设置样式表:
myPushButton->setStyleSheet("* { color: blue }");
在样式表QPushButton力QPushButton(以及任何子部件)有蓝色的文字,尽管应用程序范围内的样式表提供的更具体规则集。
若是咱们写了,结果将是相同的
myPushButton->setStyleSheet("color: blue");
除非QPushButton有子级(这不太可能),不然样式表对它们没有影响。
➡️1.遗产
在经典CSS中,当未明确设置项目的字体和颜色时,它将自动从父项继承。当使用Qt样式表,一个小部件并不会自动从其父继承控件的字体和颜色设置。
例如,考虑QGroupBox内的QPushButton:
qApp->setStyleSheet("QGroupBox { color: red; } ");
该QPushButton没有一个明确的颜色设置。所以,它具备系统颜色,而不是继承其父QGroupBox的颜色。若是要在QGroupBox及其子级上设置颜色,能够编写:
qApp->setStyleSheet("QGroupBox, QGroupBox * { color: red; }");
相反,设置字体并使用QWidget :: setFont()和QWidget :: setPalette()传播到子窗口小部件。
❤️九.相关连接或下载
- Qt样式表语法官方文档,包含详细的语法说明。
- Qt小部件,伪状态,属性清单官方文档,包含详细的伪状态,属性清单。
- Qt控件样式表示例官方文档,包含大量控件的样式表示例。
- Qt控件样式表自定义官方文档,列出了可使用样式表自定义的Qt小部件。
- FdpgQtStyleSheet源码,别忘了给个star再走!
- FdpgQtStyleSheet软件(最近csdn推出了粉丝免费下载机制,因此你只要关注,就能够免费下载了,不再须要积分了!)