QStyle(3):PixMetric和SubElement枚举

QStyle(3):PixMetric和SubElement枚举

本文为原创文章,转载请注明出处,或注明转载自“黄邦勇帅(原名:黄勇)

本文出自本人原创著作《Qt5.10 GUI完全参考手册》网盘地址:
https://pan.baidu.com/s/1iqagt4SEC8PUYx6t3ku39Q
《C++语法详解》网盘地址:https://pan.baidu.com/s/1dIxLMN5b91zpJN2sZv1MNg

若对C++语法不熟悉,建议参阅本人所著《C++语法详解》一书,电子工业出版社出版,该书语法示例短小精悍,对查阅C++知识点相当方便,并对语法原理进行了透彻、深入详细的讲解,可确保读者彻底弄懂C++的原理,彻底解惑C++,使其知其然更知其所以然。此书是一本全面了解C++不可多得的案头必备图书。

QStyle::PixMetric枚举及相关成员函数如下

virtual int QStyle::pixelMetric(PixelMetric metric, const QStyleOption *option = Q_NULLPTR, const QWidget *widget = Q_NULLPTR) const = 0;	//纯虚函数
	返回metric所关联的像素度量值,QStyle::PixMetric枚举见表13-12(完整取值请查阅帮助文档),
此枚举描述了各种像素度量(即与样式相关的大小),与函数pixelMetric()有关

在这里插入图片描述

示例13.7:自行绘制复选按钮(重新实现pixelMetric()和subElementRect()函数)
本示例比较综合,演示了怎样绘制如图13-9所示的复选按钮,并且演示了怎样重新实现pixelMetric()和subElementRect()函数,以及QStyle::PixelMetric枚举(PM_XXX)和QStyle::SubElement枚举(SE_XXX)的使用
在这里插入图片描述

图13-10为本示例各区域和各枚举代表的意义。注意:Qt内部实现的枚举所代表的意义与本示例可能会有一些不相同。

在这里插入图片描述

下面为示例代码

//m.h文件的内容
#ifndef M_H
#define M_H
#include<QtWidgets>
class B:public QProxyStyle{    Q_OBJECT
public:B(){}
//1、重新实现pixelMetric()函数,以自定义复选区域的宽度和高度
int pixelMetric(PixelMetric m, const QStyleOption *op=Q_NULLPTR,
const QWidget *w = Q_NULLPTR) const {
     	//qDebug()<<m;   //输出m的值,读者可以查看到复选框(本示例)使用了哪些PM_开头的枚举
     	switch(m){
        //注意:复选区域的高度和宽度还受到resize()函数设置的复选框大小的影响,比如当resize()
//设置的高度小于此函数返回的高度时,则复选区域的高度为resize()函数的高度,为保持与
//resize()设置的高度一致,可使用QStyleOptionButton::rect成员变量的高度值
     	//①、设置复选框复选区域的高度和宽度
        		case PM_IndicatorHeight:return 54;
        		case PM_IndicatorWidth:return 55;
     	//②、复选框复选区域与文标签之间的间距
        		case PM_CheckBoxLabelSpacing:return 88;
     	//③、其他距离使用父类的实现
        		default:return QProxyStyle::pixelMetric(m,op,w);}     }
//2、重新实现subElementRect()函数,以自定义复选按钮各区域的尺寸
 	QRect subElementRect(SubElement e, const QStyleOption *op,
                            				const QWidget *w = Q_NULLPTR) const {
//qDebug()<<e;   //可输出e以查看其值
const QStyleOptionButton *pb=qstyleoption_cast<const QStyleOptionButton*>(op);
QRect r1;
//①、计算整个复选框的大小
    		if(pb!=0)    r1=pb->rect;
//②、计算SE_CheckBoxIndicator(复选区域),其宽度和高度使用pixelMetric()函数设置的值,
//为使复选区域位于右侧,该矩形区域从复选按钮的右上角坐标计算(这样更便于计算),
//其宽度使用负值(即向左侧绘制矩形)。
QRect r(r1.topRight().x(),0,-pixelMetric(PM_IndicatorWidth,op,w),
pixelMetric(PM_IndicatorHeight,op,w));
    	//③、计算SE_CheckBoxContents(内容区域和可点击区域)
    		QRect r2(0,0,r1.width()+r.width(),r.height());
    	//④、计算SE_CheckBoxFocusRect(焦点区域),焦点区域的高度为设置的字体的高度。
    		QRect r3(0,0+(r2.height()-w->font().pointSize())/2,r2.width()-1,w->font().pointSize());
	//⑤、返回计算出来的各区域的矩形(比较简单)
    		switch(e){
   			case QStyle::SE_CheckBoxIndicator:{return r;}			//复选区域
    			case QStyle::SE_CheckBoxContents:{ return r2; }		//内容区域
    			case QStyle::SE_CheckBoxFocusRect:{return r3;}			//焦点区域
    			case QStyle::SE_CheckBoxClickRect:{return r2;}   		//可点击区域
    			default:  {return QProxyStyle::subElementRect(e,op,w);}} }
//3、重新实现drawControl()函数,以绘制自定义复选按钮的外观
 	void drawControl(ControlElement e,const QStyleOption *op,
                        			QPainter *pr, const QWidget *w = Q_NULLPTR) const {   
    		qDebug()<<e;        		//输出e可看到复选框所使用的CE_开头的枚举(控件元素)
    		qDebug()<<op->state;  		//还可查看部件的状态
    //①、获取复选按钮复选区域的矩形
    		const QStyleOptionButton *pb=qstyleoption_cast<const QStyleOptionButton*>(op);
    		QRect r=subElementRect(QStyle::SE_CheckBoxIndicator,op,w);
    //②、获取复选按钮除复选区域之外(即复选框的内容区域)的矩形
    		QRect r2=subElementRect(QStyle::SE_CheckBoxContents,op,w);
    //③、获取复选按钮的焦点矩形
    		QRect r3=subElementRect(QStyle::SE_CheckBoxFocusRect,op,w);
	//④、绘制复选按钮的初始外观
    		if(e==QStyle::CE_CheckBox){
    			pr->fillRect(r,QColor(111,1,1));				//使用红色填充复选区域
    			pr->fillRect(r2,QColor(1,111,1));			//使用绿色填充内容区域
		//⑤、绘制按下复选按钮时的外观
        		if(op->state&QStyle::State_Sunken){			//若复选按钮被按下
            		pr->fillRect(r,QColor(255,255,255)); 		//首先使用白色画刷清除之前绘制的背景
				QBrush bs(QColor(0,0,0));		
            		pr->setBrush(bs);   pr->drawEllipse(r);}  //然后使用黑色画刷bs绘制一个椭圆
                 }
	//⑥、绘制复选按钮的焦点方框
    		if(pb->state&QStyle::State_HasFocus){   			//若复选按钮获得了焦点
			//使用一个点画笔绘制一个无填充的矩形
    			QPen pn(Qt::DotLine); pr->setBrush(Qt::NoBrush); pr->setPen(pn); pr->drawRect(r3);}
	//⑦、绘制复选按钮的文本(垂直居中于r2),此步骤需最后绘制,否则可能会被绘制的其他图形覆盖。
    		pr->drawText(r2,Qt::AlignVCenter,pb->text);	}	};
#endif // M_H

//m.cpp文件的内容
#include "m.h"
int main(int argc, char *argv[]){    QApplication aa(argc,argv);
    QWidget w;
    QPushButton *pb1=new QPushButton("AAA",&w); pb1->move(22,22);pb1->resize(221,22);
    QCheckBox *pc=new QCheckBox("CCC",&w); pc->move(99,55);
    QFont f;    f.setPointSize(22);    pc->setFont(f);		//为复选按钮设置字体
    pc->setStyle(new B());   							//复选按钮使用自定义样式
    w.resize(444,333);    w.show();    return aa.exec();  }

本文作者:黄邦勇帅(原名:黄勇)

在这里插入图片描述

Guess you like

Origin blog.csdn.net/hyongilfmmm/article/details/83247683