Qt 之 样式表的使用——样式选择器(上篇)

来源:互联网 发布:开票软件打不开结束 编辑:程序博客网 时间:2024/06/10 01:54

一、简述

时隔上一篇文章已经十多天没有更新博客了,实在惭愧,这些天也都在忙活着各种事情。不过时间还是海绵中的水,挤一挤还是有的。

今天继上篇Qt 之 样式表的使用之设置样式的方法 ,来详细谈一谈Qt中样式选择器的一些用法。

经过之前对样式选择器的理解以及查阅Qt文档,整理了一下样式选择器的用法。本篇文章篇幅较长(辛辛苦苦花了三个晚上的时间测试样式、截取效果图、编写文章╮(╯▽╰)╭),对每种样式选择器进行了详细介绍以及详细的示例(上篇中先介绍前四种样式选择器,后三种将在下篇中介绍)。

二、样式选择器

我们先看一下Qt文档中对于不同选择器的解释:

这里写图片描述

可以在Qt助手中输入 The Style Sheet Syntax 然后查看 Selector Types


我们可以看到Qt有7种样式选择器,对于不同样式选择器也有相应的解释,那么下面我就给大家简单讲一讲这几种选择器的用法。

(1)、通用选择器(Universal Selector)

这里写图片描述

我们可以看到文档的解释:适用于所有的控件()。

A、 *{“样式”}

比如我们在样式文件style.qss中写了这么一句 * {color:red}; ,那么加载这个样式文件的窗口上所有部件的文字字体颜色都为红色,所以说如果使用 *{“样式”},那么 {“”} 中的样式将生效于全局。我们一般用于设置全局的通用属性,比如全局的字体的颜色,大小,字体格式等。

B、 作用域 *{“样式”}

这里写图片描述

看上面第一行样式,在 * 前加上了QStackedWidget ,这有什么用呢,我们看一下效果。

这里写图片描述

我们看到QToolButton字体是黑色,而QPushButton字体为红色,这样就很好理解了,因为QPushButton在QStackedWidget 中,而QToolButton在最外层Widget中,所以我们这里使用 QStackedWidget *{color:red;} 限制了样式的作用域,只局限于设置QStackedWidget 中所有控件的样式。


既然 *{“样式”} 可以设置全局的样式,那么我设置了全局字体为红色之后,还可以单独设置某一个控件的字体为其他颜色吗?

这当然是可以的,下面我给QPushButton单独设置了 color:blue;样式,而QToolButton不设置任何样式,我们看到QPushButton字体确实是蓝色,而QToolButton字体为全局设置的红色。

这里写图片描述


(二)、类型选择器(Type Selector)

这里写图片描述

类型选择器适用于给某一类型的控件设置样式,比如QPushButton、QToolButton、QLabel 、QWidget 等等。

同时呢,在我们给该类型的控件设置样式时,它的子类也会被设置该样式


下面举几个例子,来看一看类型选择器的效果:

A、单独给某一个控件设置样式

我们给QPushButton设置第一个或者第二个样式都会让字体变为蓝色,因为QPushButton是QWidget的子类,所以这里验证了文档中所说的子类也会被设置该样式。

QWidget{color:blue;}
或者
QPushButton{color:blue;}

这里写图片描述


B、给一个控件的父控件设置样式

下面我们给最顶层 QWidget 或者 QStackedWidget 设置如下样式都会使在该控件区域内的控件字体设置为蓝色,如果我们给 QStackedWidget 设置下面的样式,而QToolButton不在QStackedWidget 区域内,那么QToolButton字体就不会被设置为蓝色。

QWidget{color:blue;}

这里写图片描述

那么如果我们给最顶层 QWidget 或者 QStackedWidget设置了如下样式呢?

很显然,没有任何效果,因为 这几个控件都不是 QStackedWidget 的子类,所以样式无效。

QStackedWidget{color:blue;}

这里写图片描述


(三)、属性选择器(Property Selector)

这里写图片描述

我们可以看到文档对属性选择器解释比较详细,由此可见属性选择器相对其他选择器相对复杂一些,但是可扩展程度更高。大家也可以自己翻译理解一下这段文字的意思,下面就文档给出的解释进行一个详细的介绍。

首先第一段告诉我们属性选择器支持控件所有能够通过QVariant::toString()方法转换的静态属性(自带属性),同时支持特殊类属性

这里有两点需要解释一下:

A、能够通过QVariant::toString()方法转换的原始属性

这里写图片描述

我们要得到一个控件的某个属性值需要通过property()方法来获取,而property()方法返回一个QVariant类型的值。QVariant就像一个Qt基本数据类型集合,可以转换成大多数基本数据类型。上文中提到能够通过QVariant::toString()方法转换的原始属性,也就是说该属性值可以通过QVariant::toString()方法转换成QString类型,我们再看一下QVariant::toString()方法的介绍。

这里写图片描述

从上面可以看到,并不是所有的数据类型都很转成QString,而文档也例举出了能够转成QString的数据类型。 所以属性类型为以上类型的都支持属性选择器的使用。

这里写图片描述

我们在QtDesigner中先看一下QPushButton的原始属性。从上图中可以看到QPushButton继承了QObject、QWidget、QAbstractButton的属性,而QPushButton自己附带了三个属性。

下面举几个简单的例子就很容易理解了。

我们给最顶层QWidget设置如下样式:

QPushButton[text=”PushButton”]{color:red;}
或者
QWidget[text=”PushButton”]{color:red;}

这里写图片描述

从上图中看到,文字内容为“PushButton”的按钮字体颜色被设置成了红色。而其他控件的字体颜色没有设置成红色。

第一中样式,先限制了控件必须是QPushButton,然后text属性值必须是“PushButton”。

QPushButton[text=”PushButton”]{color:red;}

第二种样式,text属性值为“PushButton”的QWidget控件字体颜色会被设置为红色,我们可以看到第一个QPushButton控件字体设置成了红色。但是QWidget没有text属性,而QPushButton有text属性说明属性选择器设置的样式对子类同样生效

QWidget[text=”PushButton”]{color:red;}


下面我们将两个按钮的 “default”属性置为 true,然后给最顶层QWidget设置如下样式:

QPushButton[default=”true”]{color:red;}
或者
QWidget[default=”true”]{color:red;}

这里写图片描述

这里写图片描述

我们看到两个按钮文字颜色都被设置为红色。

这里第二种样式,同上面一样,说明属性选择器设置的样式对子类同样生效

QWidget[default=”true”]{color:red;}

B、特殊类属性

我们对最顶层QWidget设置如下样式,我们看到只有QPushButton字体颜色设置为红色,其他控件的字体颜色没有变化。其实也很好理解,就是类的类型为QPushButton的控件字体都会被设置为红色。

*[class=”QPushButton”]{color:red;}
或者
QWidget[class=”QPushButton”]{color:red;}

这里写图片描述

这里需要注意一点,如果我们使用下面的样式对QPushButton或者QWidget的子类是没有效果的。关于这一点可以看一下下面第四点类选择器

*[class=”QWidget”]{color:red;}


C、动态属性

第二段解释告诉我们属性选择器还可以支持自定义的动态属性,什么是动态属性呢,就是用户手动添加的属性,这里我们可以通过QtDesigner直接添加或者使用代码为控件添加属性。

(1)、通过QtDesigner添加动态属性

这里写图片描述

这里我们可以通过点击 + 按钮来添加自定义的动态属性。

点击 + 按钮后弹出创建动态属性的窗口,我们可以自定义属性的类型及名称。要注意的一点是,如果我们添加的动态属性是用于属性选择器来设置样式的,那么我们添加的属性类型为能够通过QVariant::toString()方法转换成QString的类型。

这里写图片描述

我们手动为第一个QPushButton控件添加一个属性,名称为“IsNew”,类型为bool,然后设置如下样式

QPushButton[IsNew=”true”]{color:red;}

这里写图片描述

这里写图片描述

(2)、通过代码添加动态属性

ui.pushButton->setProperty("IsNew", true);this->setStyleSheet("QPushButton[IsNew="true"]{color:red;}");

运行效果同上。


D、使用“~=”代替“=”

第三段解释是针对类型为QStringList 的属性。当属性类型为QStringList 时,我们可以使用“~=”来代替“=”,至于为什么,举个例子大家就明白了。

Instead of =, you can also use ~= to test whether a Qt property of type QStringList contains a given QString.

我们使用QtDesigner 给 QPushButton控件添加一个QStringList类型的属性:StrListProperty

这里写图片描述

然后我们先添加一个字符串”123”,
这里写图片描述
这里写图片描述

然后我们使用如下样式:

*[StrListProperty=”123”]{color:red;}
或者
*[StrListProperty~=”123”]{color:red;}

这里写图片描述

我们发现两种方式按钮的颜色都成功设置成了红色。下面我们给QStringList类型属性 StrListProperty 再添加一个字符串”456”。

这里写图片描述

*[StrListProperty=”123”]{color:red;}
*[StrListProperty=”456”]{color:red;}
或者
*[StrListProperty~=”123”]{color:red;}
*[StrListProperty~=”456”]{color:red;}

再次测试后发现上两种方式无法设置样式,而后两种可以成功设置样式。所以,如果当前的属性类型为QStringList时,如果有只有一个字符串时可以用“~=”或者“=”,但是如果包含两个及以上字符串时必须要使用“~=”

一般如果控件的属性类型为QStringList时,建议就用“~=”来代替“=”,不要再使用“=”,以免导致样式设置不生效

注意:

如果我们设置完了样式后,控件的属性值变了,那么需要重新设置样式来使其生效。


综述

属性选择器是建立在其他选择器基础之上,然后附加了属性匹配条件。

如:

通用选择器 : *{“样式”}

属性选择器 :*[属性=”“]{ “样式”} (样式生效于全局,限定了属性值)
例如:
*[class=”QWidget”]{color:red;}
*[default=”true”]{color:red;}


类型选择器 : 类型{“样式”}

属性选择器 :类型[属性=”“]{ “样式”} (样式对子类同样可以生效,限定了属性值)
例如:
QWidget[class=”QPushButton”]{color:red;}
QPushButton[default=”true”]{color:red;}


(四)、类选择器(Class Selector)

这里写图片描述

“.” + 类名
.QPushButton 适用于 所有 QPushButton的实例 , 但不会设置QPushButton 的子类。

我们给最顶层窗口 QWidget 设置如下样式,我们看到界面上所有的控件字体都没有变化,说明类选择器只对该类设置样式,对该类的子类没有任何影响。

.QWidget{color:blue;background:yellow}

这里写图片描述

同时解释中提到了This is equivalent to *[class~=”QPushButton”].,所以这里我们也可以用属性选择器中的类属性来达到类选择器一样的效果。(在属性选择器-特殊类属性那一点已经提到)


今天文章讲述了四种样式选择器的一些基本用法,其中用了大量的篇幅讲解了属性选择器的应用,剩下的三种选择器的将在下一篇中详细介绍。虽然花了不少时间整理,但是对于选择器的使用有了更深的理解。如果对文章中有疑问或者质疑的欢迎一起交流。


更新于——2017/3/22 晚(添加了属性选择器相关内容)

2 0
原创粉丝点击