工程项目中,需要在按钮QPushButton上同时显示文本和图标,文本在左,图标在右,并且操作过程中按钮样式的能够跟随着变化,比如按下按钮的时候,文本和图标能够显示按下的状态等。
控制文本变化,可以通过qss样式表来实现,并且难道不大,但是同时需要在按钮上显示图标,并且能够控制图标的变化。由于第一次接受到这样的需求场景,所以需要研究尝试简单可行的办法。
开始的想法是自定义QPushButton按钮,但是实现难度大,而且复杂。所以,考虑是否能够通过样式表来实现图标显示要求。
本文介绍两种显示图标的方法,经过调试,第二种方法满足需求,下来就来详细说明分析实现的过程,再梳理总结两种方法的优缺点。最后扩展内容,实现QListView的item,左侧显示图标,右侧显示文本的效果。
盒子模型
正式说明功能实现之前,需要了解盒子模型,主要是关于background-origin的三个属性值,分别为border、padding、content。
属性background-origin的功能是设置背景图像相对于什么类型来定位。
![187c47567e10bb43d979a0adac370af7.png](https://img-blog.csdnimg.cn/img_convert/187c47567e10bb43d979a0adac370af7.png)
盒子模型如上图所示,最外层为边框border, 中间为内边距padding, 最里面为内容content。如果设置 background-origin为border表示图像背景相对于border左上角来定位,同样的,如果设置 background-origin为content, 那么图像背景就相对于content的左上角的定位。
icon方式显示图标
基于图标icon来实现按钮同时显示图标和文本的功能,其样式表设置如下, 使用qproperty-icon属性来添加图标。
![83bf6c1235cebb50b1abdd0a2538dcaf.png](https://img-blog.csdnimg.cn/img_convert/83bf6c1235cebb50b1abdd0a2538dcaf.png)
运行效果如下所示,图标在左,文本在右。
![88b5aad23052892cb24a144b18e2b880.png](https://img-blog.csdnimg.cn/img_convert/88b5aad23052892cb24a144b18e2b880.png)
如果想要放大按钮图标,那么可以添加属性qproperty-iconSize来实现。
![d5f3ea421040c5c9873a11f9ba30fc4a.png](https://img-blog.csdnimg.cn/img_convert/d5f3ea421040c5c9873a11f9ba30fc4a.png)
如果想要将图标显示在文本的右侧,可以通过添加Qt::LayoutDirection::RightToLeft的属性来实现。
![183a76c1ec55fa89143a10002b32461b.png](https://img-blog.csdnimg.cn/img_convert/183a76c1ec55fa89143a10002b32461b.png)
运行效果如下所示,可以看到文本在左,图标在右。
![e74c4f4f803f75f68200ade3fda80315.png](https://img-blog.csdnimg.cn/img_convert/e74c4f4f803f75f68200ade3fda80315.png)
背景图像方式显示图标
采用背景图像方式来显示图标,那么就需要background-origin属性登场。其样式表进行如下设置。background-image设置背景图像,background-repeat为none表示设置背景图像不重复,background-position设置背景图像的位置,background-origin为content表示背景图像是相对于内容框来定位的。
![08d689bb854139f79568a992fb1fa620.png](https://img-blog.csdnimg.cn/img_convert/08d689bb854139f79568a992fb1fa620.png)
运行效果如下所示,可以发现图标太靠近按钮右边缘,不太美观,那么怎么修改呢?
![e8b7e3ee461199a49cdfe4b666d1d1eb.png](https://img-blog.csdnimg.cn/img_convert/e8b7e3ee461199a49cdfe4b666d1d1eb.png)
基于盒子模型的分析,目前图标是位于内容框,那么只要调整内右边距的大小即可,比如设置内右边距的大小为20px, 即添加属性padding-right: 20px。
再次运行的效果图如下,可以发现图标已经偏离按钮的右边缘。
![a6a913b1bfe7190d4465e7960132f33c.png](https://img-blog.csdnimg.cn/img_convert/a6a913b1bfe7190d4465e7960132f33c.png)
如果想要悬停或者按下按钮,图标发生改变,那么再添加如下样式表,悬停的时候更换背景图,按下的时候更换其他背景图。
![b120c7a871c6acac2e518a2a9742517c.png](https://img-blog.csdnimg.cn/img_convert/b120c7a871c6acac2e518a2a9742517c.png)
最后运行的动态效果图
![c9721efcd23774ee998c7bf06c3f2f98.gif](https://img-blog.csdnimg.cn/img_convert/c9721efcd23774ee998c7bf06c3f2f98.gif)
两种方式的优缺点
icon方式显示图标的优点是简单,并且能够控制图标的大小,缺点是图标和文本之间的间隔很难自由调整,并且通过样式表无法动态更换图标。
背景图像方式显示图标的优点是图标和文本之间的间隔能够自由调整,能够动态更换图标,确定是背景图像无法自适应,如果你的屏幕不适应自适应功能,那么这种方法是比较好的。
扩展
最后再来说明如何实现QListView的item,左侧显示图标,右侧显示文本的效果。设置的样式表内容如下,这里设置background-origin为border,表示背景图像相对于边框来定位。
![bc31de0f17913930c3ebfbc700e62ff9.png](https://img-blog.csdnimg.cn/img_convert/bc31de0f17913930c3ebfbc700e62ff9.png)
运行的界面效果如下,如果想要加大图标与文本之间的间隔,那么需要设置内左边距。
![468b0abd0efdc4db3398720a8ffd191e.png](https://img-blog.csdnimg.cn/img_convert/468b0abd0efdc4db3398720a8ffd191e.png)
总结
至此,采用样式表,实现控件同时显示图标和文本信息的功能已经讲解完毕,界面的设计,需要平时不断积累和总结,熟悉了控件的各种属性之后,就能够轻松自如应对各种界面变化。另外,对于本文讲解的内容,如果有牛人,能够提供更好的解决方案,欢迎分享!