【Qt界面优化】—— QSS 的介绍

目录

(一)背景介绍

(二)基本语法 

 (三)QSS设置方式

3.1 指定控件样式设置

3.2 全局样式设置 

3.3 使用Qt Designer编辑样式 

(四)选择器 

4.1 选择器概况

4.2 子控件选择器(Sub-Controls)

4.3 伪类选择器(Pseudo-States)

(五)样式属性

5.1 盒模型(BoxModel)

(六)控件样式示例

6.1 按钮

6.2 复选框 

总结


(一)背景介绍

在网页前端开发领域中,CSS是⼀个至关重要的部分.描述了⼀个网页的"样式".从起到对网页美化的 作用。

  • 所谓样式,包括不限于大小,位置,颜色,背景,间距,字体等等.

  • 现在的网页很难找到没有CSS的.可以说让"界面好看"是⼀个刚需. 

"好看"这个事情有没有意义呢?是否⼀个软件,能满足核心功能即可,界面好看无所谓呢? 参考知乎上的这个帖子:https://www.zhihu.com/question/30918916/answer/49934463 

  •  网页开发作为GUI的典型代表,也对于其他客户端GUI开发产⽣了影响.Qt也是其中之⼀.

Qt 仿照CSS的模式,引入了QSS,来对Qt中的控件做出样式上的设定,从而允许程序猿写出界面更好看的代码.

  • 同样受到HTML的影响,Qt还引⼊了QML来描述界面,甚至还可以直接把⼀个原生的html页面加载到界面上.这部分内容这里不做讨论.

当然,由于Qt本身的设计理念和网页前端还是存在⼀定差异的,因此QSS中只能支持部分CSS属性. 整体来说QSS要比CSS更简单⼀些. 

注意: 如果通过QSS设置的样式和通过C++代码设置的样式冲突,则QSS优先级更⾼


(二)基本语法 

对于CSS来说,基本的语法结构非常简单.

选择器
{
    属性名: 属性值; 
}

QSS沿用户了这样的设定.

选择器
{
    属性名: 属性值; 
}

其中:

  1. 选择器描述了"哪个widget要应用样式规则".
  2. 属性则是⼀个键值对,属性名表示要设置哪种样式,属性值表示了设置的样式的值.

例如:

QPushButton { color: red; }

 或者

QPushButton {
    color: red;
}
  • 上述代码的含义表示,针对界面上所有的QPushButton,都把文本颜色设置为 “红色”

代码示例:

1) 在界面上创建⼀个按钮.

2) 编写代码,设置样式 

Widget::Widget(QWidget *parent)
 : QWidget(parent)
 , ui(new Ui::Widget)
 {
     ui->setupUi(this);
     ui->pushButton->setStyleSheet("QPushButton { color: red; }");
 }

3) 运行程序,观察效果.可以看到文本已经是红色了.

  • 上述代码中,我们是只针对这⼀个按钮通过 setStyleSheet 方法设置的样式.此时这个样式 仅针对该按钮生效.如果创建其他按钮,其他按钮不会受到影响. 

 (三)QSS设置方式

3.1 指定控件样式设置

QWidget 中包含了 setStyleSheet 方法,可以直接设置样式. 上述代码我们已经演示了上述设置方式.

另⼀方面,给指定控件设置样式之后,该控件的子元素也会受到影响.


代码示例:

1) 在界面上创建⼀个按钮

2) 修改widget.cpp,这次我们不再给按钮设置样式,而是给Widget设置样式(Widget是 QPushButton的父控件). 

Widget::Widget(QWidget *parent)
 : QWidget(parent)
 , ui(new Ui::Widget)
{
     ui->setupUi(this);
     // 给Widget 本⾝设置样式
     this->setStyleSheet("QPushButton { color: red;} ");
}

3) 运行程序,可以看到样式对于子控件按钮同样会生效.


3.2 全局样式设置 

还可以通过 QApplication 的 setStyleSheet 方法设置整个程序的全局样式.

全局样式优点:

  • 使同⼀个样式针对多个控件生效,代码更简洁.
  • 所有控件样式内聚在⼀起,便于维护和问题排查.

代码示例:

1) 在界面上创建三个按钮.

2) 编辑main.cpp,设置全局样式 

int main(int argc, char *argv[])
{
     QApplication a(argc, argv);
     //设置全局样式
 
     a.setStyleSheet("QPushButton { color: red; }");

     Widget w;
     w.show();
     return a.exec();
}

3) 运行程序,可以看到此时三个按钮的颜色都设置为红色了.


代码示例:样式的层叠特性

如果通过全局样式给某个控件设置了属性1,通过指定控件样式给控件设置属性2,那么这两个属性都会产生作用.

1) 在界面上创建两个按钮

2) 编写main.cpp,设置全局样式,把按钮文本设置为红色. 

int main(int argc, char *argv[])
{
     QApplication a(argc, argv);
     // 设置全局样式
 
     a.setStyleSheet("QPushButton { color: red; }");

     Widget w;
     w.show();
     return a.exec();
}

3) 编写widget.cpp,给第⼀个按钮设置字体大小

Widget::Widget(QWidget *parent)
 : QWidget(parent)
 , ui(new Ui::Widget)
{
     ui->setupUi(this);

     //设置指定控件样式
     ui->pushButton->setStyleSheet("QPushButton { font-size: 50px} ");

}

4) 运行程序,可以看到,对于第⼀个按钮来说,同时具备了颜色和字体大小样式.而第⼆个按钮只有颜色样式.

  • 说明针对第⼀个按钮,两种设置方式设置的样式,叠加起来了.

  • 形如上述这种属性叠加的效果,我们称为"层叠性".
  • CSS全称为CascadingStyleSheets,其中Cascading就是"层叠性"的意思QSS也继承了这 样的设定.
  • 实际上把QSS叫做QCSS也许更合适⼀些~ 

3.3 使用Qt Designer编辑样式 

QSS也可以通过QtDesigner直接编辑,从而起到实时预览的效果.同时也能避免C++和QSS代码的耦合.

代码示例:使用Qt Designer编辑样式

1) 在界面上创建⼀个按钮

2) 右键按钮,选择"改变样式表" 

3) 在弹出的样式表编辑器中,可以直接填写样式.填写完毕,点击OK即可. 

4) 此时QtDesigner的预览界面就会实时显示出样式的变化. 

5) 运行程序,可以看到样式确实发生了改变. 

这种方式设置样式,样式内容会被以xml格式记录到ui文件中. 

<property name="styleSheet">
<string notr="true">QPushButton { color: red; }</string>
</property>

同时在控件的 styleSheet 属性中也会体现.

当我们发现⼀个控件的样式不符合预期的时候,要记得排查这四个地方:

  • 全局样式
  • 指定控件样式
  • qss文件中的样式
  • ui文件中的样式 

(四)选择器 

4.1 选择器概况

QSS的选择器支持以下几种:

  •  总体来说,QSS选择器的规则和CSS选择器基本⼀致.
  • 上述选择器咱们也不需要全都掌握,就只熟悉最常用的几个即可(上述加粗的).

代码示例:使用类型选择器选中子类控件

1) 在界面上创建⼀个按钮.

2) 修改main.cpp,设置全局样式 

  • 注意,此处选择器使用的是QWidget . QPushButton也是QWidget 的子类,所以会到, QWidget 选择器的影响
int main(int argc, char *argv[])
{
     QApplication a(argc, argv);
     //设置全局样式
 
     a.setStyleSheet("QWidget { color: red; }");

     Widget w;
     w.show();
     return a.exec();
}

3) 运行程序,可以看到按钮的文本颜色已经是红色了.

5) 如果把上述样式代码修改为下列代码 

a.setStyleSheet(".QWidget { color: red; }");
  • 此时按钮的颜⾊不会发生改变.此时只是选择 QWidget 了. 而不会选择 QWidget 的子类QPushButton


4.2 子控件选择器(Sub-Controls)

 

有些控件内部包含了多个"子控件".比如QComboBox的下拉后的面板,比如QSpinBox的上下按钮等.

可以通过子控件选择器 :: ,针对上述子控件进行样式设置.

代码示例:设置下拉框的下拉按钮样式

1) 在界面上创建⼀个下拉框,并创建几个选项

2) 创建 resource.qrc ,并导入图片 down.png 

3) 修改main.cpp,编写全局样式

  • 使用子控件选择器 QComboBox::down-arrow 选中了
  • 再通过 image 属性设置图片. 
int main(int argc, char *argv[])
{
     QApplication a(argc, argv);

     QString style = "";
     style += "QComboBox::down-arrow { image: url(:/down.png) }";
     a.setStyleSheet(style);

     Widget w;
     w.show();
     return a.exec();
}

4) 执行程序,观察效果 


4.3 伪类选择器(Pseudo-States)

伪类选择器,是根据控件所处的某个状态被选择的.例如按钮被按下,输入框获取到焦点,⿏标移动到某 个控件上等.

  • 当状态具备时,控件被选中,样式生效.
  • 当状态不具备时,控件不被选中,样式失效. 

使用 : 的方式定义伪类选择器.

常用的伪类选择器

 这些状态可以使用 !来取反.比如 :!hover 就是⿏标离开控件时, :!pressed 就是⿏标松开时,等等.


(五)样式属性

QSS中的样式属性非常多,不需要都记住.核心原则还是用到了直接去查. 大部分的属性和CSS是非常相似的。(文档的 Qt Style Sheets Reference 章节详细介绍了哪些控件可以设置属性,每个控件都能设置哪些属性等.

5.1 盒模型(BoxModel)

在文档的Customizing Qt Widgets Using Style Sheets 的 The Box Model 章节介绍了盒模型.

⼀个遵守盒模型的控件,由上述几个部分构成.

  • Content 矩形区域:存放控件内容.比如包含的文本/图标等.
  • Border 矩形区域:控件的边框.
  • Padding 矩形区域:内边距.边框和内容之间的距离.
  • Margin 矩形区域:外边距.边框到控件

默认情况下,外边距,内边距,边框宽度都是0.

可以通过⼀些QSS属性来设置上述的边距和边框的样式.


代码示例:设置边框和内边距 

 1) 在界面上创建⼀个label

2) 修改main.cpp,设置全局样式 

int main(int argc, char *argv[])
{
     QApplication a(argc, argv);
     a.setStyleSheet("QLabel { border: 5px solid red; padding-left: 10px; }");

     Widget w;
     w.show();
     return a.exec();
}

3) 运行程序,可以看到样式发生了变化

 


(六)控件样式示例

下⾯给出⼀些常⽤控件的样式示例.

6.1 按钮

代码示例:自定义按钮

1) 界面上创建⼀个按钮

2) 右键->改变样式表,使用QtDesigner设置样式

QPushButton {
     font-size: 20px;
     border: 2px solid #8f8f91;
     border-radius: 15px;
     background-color: #dadbde;
}
QPushButton:pressed {
     background-color: #f6f7fa;
}

3) 执行程序,可以看到效果

 


代码示例:设置外边距

为了方便确定控件位置,演示外边距效果,我们使用代码创建⼀个按钮.

1) 修改widget.cpp,创建按钮,并设置样式.

Widget::Widget(QWidget *parent)
 : QWidget(parent)
 , ui(new Ui::Widget)
 {
     ui->setupUi(this);
     QPushButton* btn = new QPushButton(this);
     btn->setGeometry(0, 0, 100, 100);
     btn->setText("hello");
     btn->setStyleSheet("QPushButton { border: 5px solid red; margin: 20px; }");
     const QRect& rect = btn->geometry();
     qDebug() << rect;
 }

2) 运行程序,可以看到,当前按钮的边框被外边距挤的缩小了.但是获取到的按钮的的. Geometry 是不变


6.2 复选框 

代码示例:自定义复选框

1) 创建⼀个 resource.qrc 文件,并导入以下图片.

使用黑色作为默认形态. 使用黑色作为hover形态. 使用红色作为pressed形态. 

2) 创建⼀个复选框 

3) 编辑复选框的样式

QCheckBox {
     font-size: 20px;
}
QCheckBox::indicator {
     width: 20px;
     height: 20px;
}
QCheckBox::indicator:unchecked {
     image: url(:/checkbox-unchecked.png);
}
QCheckBox::indicator:unchecked:hover {
     image: url(:/checkbox-unchecked_hover.png);
}
QCheckBox::indicator:unchecked:pressed {
     image: url(:/checkbox-unchecked_pressed.png);
}
QCheckBox::indicator:checked {
     image: url(:/checkbox-checked.png);
}
QCheckBox::indicator:checked:hover {
     image: url(:/checkbox-checked_hover.png);
}
QCheckBox::indicator:checked:pressed {
     image: url(:/checkbox-checked_pressed.png);
}

4) 运行程序,可以看到此时的复选框就变的丰富起来了.


除了上述之外,还有包括像单选框、列表、输入框等各种控件,在这里就不一一演示了!! 


总结

QSS本身给Qt提供了更丰富的样式设置的能力,但是整体来说QSS的功能是不如CSS的.

在CSS中,整个网页的样式,都是CSS一手负责,CSS功能更强大,并且也更可控.

相⽐之下,Qt中是以原生api为主,来控制控件之间的尺寸,位置等,QSS只是起到辅助的作用.

而且Qt中提供的⼀些"组合控件"(像QComboBox,QSpinBox等)内部的结构是不透明的,此时进行⼀ 些样式设置也会存在⼀定的局限性.

另外,做出好看的界面,光靠QSS是不够的.更重要的是需要专业美工做出设计稿.这里主要是了解这个技术

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

起飞的风筝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值