Qt 花里胡哨系列(一)——QStyleSheet

前言

转眼间过去了大半个月没整理了,这期间一直在忙活着公司的事,也有不少心得体会,后续可以整理整理分享出来,这篇简单聊下qt中界面的美化(这里不提自绘图形,纯靠qt提供的方式)。

QStyleSheet

鼓捣过前端的应该对css再熟悉不过了,当前现在又是less啊sass/scss什么的,当然归根结底还是css啊,只是写法不同罢了,就跟前端框架vue/react/angular什么的,在浏览器能展示的最终还是html+js+css(个人理解)。

客户端当然也有美化界面的需求了,毕竟哪怕是工厂用的现在界面也是有一定要求的,当然没网页审美这么高,像winform通过设置控件的背景色啊边框等等的属性来实现,wpf的话就类似html的写法,当然也是一个个属性。

回归本题,qt中实现样式调整的方式有两种,一个通过直接在设计器中设置QStyleSheet这一属性(当然也是属性,毕竟是客户端的一个个类),但是写法上就比较类似于css了,待会儿有示例可以看下,看完就会觉得,哦,挺熟悉;另外一种方式是通过加载qss文件来实现样式,两种方式各有各的利弊吧,简单来说就是QStyleSheet比较直观,所写即所得;qss规整,利于维护,当然缺点就是对应的互换,想想写html的时候没有一个css文件全都是在控件中写style的屎山般的痛苦。

前面既然说了类似css,那当然也存在父级控件样式(非指明类)适用子级,子级样式覆盖父级设置,简单来说就是父级设置了背景白色,子级不设置的就也是白色,设置了红色那子级就是红色。

个人推荐是如果工程界面相对较多,可以使用加载qss文件的方式,如果只有一两个界面并且控件也不是那么多的话,咋简单咋来。

通用样式

因为基本上控件都是基于Widget,所以大多数控件的样式设置基本类似,在qss中通配符表示所有的就是*(所以说跟css很像),通配符的用法如下表。

通配符说明示例
*表示所有* {}
类名表示所有属于这一类,可以理解为html中的classQWidget {}
只有这一类,不包含子类.QWidget {}
属性选择所有属于这一类的且属性为所设置的QPushButton[flat==”false”] {}
#名称表示这个控件#pushButton1 {}
类中类父类中包含子类的所有QWidget QPushButton {}

常用属性如下(越写越多,用的时候边查边用吧)。

  • margin
  • padding
  • background
  • background-color
  • border
  • font
  • color
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
* {
margin: 0;
padding: 0;
outline: 0px;
background: #F5F7FA;
border: none;
font: normal 12px "微软雅黑";
}

QWidget {
background: #F5F7FA;
}

#pushButton_1 {
background: #438CFF;
border-radius: 0px;
border-bottom-left-radius:6px;
border-top-left-radius:6px;

}

其他特殊的

另外对于不同的控件,也有不同的状态样式,例如按钮的点击、鼠标悬浮、禁用,单选/多选的选中,下拉的箭头,选项卡的选项按钮等等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#pushButton_1:hover {
background: rgba(67,140,255,0.7);
color: #FFFFFF;
}

#pushButton_1:checked {
background: rgba(67,140,255,0.8);
color: #FFFFFF;
}

#pushButton_1:pressed {
background: #FF5722;
color: #FFFFFF;
}

QPushButton:disabled{
background: #909399;
}

QRadioButton{
spacing: 2px;
color: white;
}

QRadioButton::indicator {
width: 45px;
height: 30px;
}

QRadioButton::indicator:unchecked {
image: url(:/image/off.png);
}

QRadioButton::indicator:checked {
image: url(:/image/on.png);
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
QListWidget {
color: #606266;
border: 1px solid #DCDFE6;
padding: 10px;
}

/**列表项*/
QListWidget::item {
color: #606266;
height: 40px;
font-size: 16px;
}

/**列表项扫过*/
QListWidget::item:hover, QTreeWidget::item:hover {
background: #70B6FF;
color: #FFFFFF;
}

/**列表项选中*/
QListWidget::item::selected:active {
color: #FFFFFF;
background: #409EFF;
border: none;
}

QListWidget::item:selected {
color: #FFFFFF;
border: none;
background: #409EFF;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
QComboBox, QFontComboBox, QLineEdit, QTextEdit {
border: 1px solid #BBBBBB;
border-radius: 6px;
background: transparent;
color: #606266;
font-size: 14px;
padding: 0 5px 0 10px;
}

/*下拉框的显示框效果*/
QComboBox QAbstractItemView, QFontComboBox QAbstractItemView {
background: #FFFFFF;
height: 20px;
padding: 10px 10px 10px 10px;
outline: 0px;
}

QComboBox::down-arrow, QFontComboBox::down-arrow {
image: url(":/image/under.png");
}

QComboBox QAbstractItemView::item, QFontComboBox QAbstractItemView::item {
margin: 3px;
}

QComboBox QAbstractItemView::item:hover, QFontComboBox QAbstractItemView::item:hover {
color: #FFFFFF;
background-color: #409EFF;
}

QComboBox QAbstractItemView::item:selected, QFontComboBox QAbstractItemView::item:selected {
color: #FFFFFF;
background-color: #409EFF;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
QSpinBox, QDoubleSpinBox{
border: 1px solid #707070;
border-radius: 4px;
padding: 3px 5px 3px 5px;
background: none;
selection-background-color: #409EFF;
selection-color: #FFFFFF;
}

QSpinBox::up-button, QDoubleSpinBox::up-button {
image:url(:/image/add_top.png);
width: 15px;
height: 10px;
padding: 3px 5px 3px ;

}
QSpinBox::down-button, QDoubleSpinBox::down-button {
image:url(:/image/add_bottom.png);
width: 15px;
height: 10px;
padding: 3px 5px 3px ;
}

有些特殊的样式属性需要留意下,例如设置图片,有多种方式,可以通过直接设置pixmap,也可以通过background:url(),推荐使用border-image:url(),这三种方式的效果可以自己测试下(当然也是根据需要)。

因为样式这个东西,具体实现需要调整哪些还是比较麻烦的,也比较多,这东西最好还是用到了去查手册,qt安装之后有个assistant.exe,可以在这个助手中查找很多相关的资料。

手册查找stylesheet

加载字体

样式调完了,肯定会有人觉得这个默认字体不好(当然qt支持字体选择,具体有哪些就可以自己在设计器里字体那一栏找了,那个下拉基本上是你电脑已经安装的字体),当然也可以动态加载字体文件来设置全局字体,比如在网上找了个比较华丽的字体,我们怎么加载呢,可以直接通过一段代码来直接用,注意路径就行。

1
2
3
4
5
6
7
int fontId = QFontDatabase::addApplicationFont("./FONT/weiruan.ttf");
if (fontId >= 0)
{
QString fontName = QFontDatabase::applicationFontFamilies(fontId).at(0);
QFont font(fontName);
QApplication::setFont(font);
}

小结

好了,花里胡哨的一篇样式篇就这样结束了,为啥没放实现的效果图呢,因为我觉得我这审美还是别拿出来秀了,真是想鼓捣客户端的界面,其实也可以参考很多前端样式,像ant啊element之类的,毕竟人家大厂出品相对精品嘛,但是也不要过于追求花里胡哨,毕竟gui还是别要求太高了,有时候为了一个特效画个三五天不值当,当然仁者见仁,这事不好说。


Qt 花里胡哨系列(一)——QStyleSheet
http://www.aprilblank.top/qt/style.html
作者
AprilBlank
发布于
2022年8月19日
许可协议