QStyle(3):PixMetric和SubElement枚舉

QStyle(3):PixMetric和SubElement枚舉

若對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();  }

本文作者:黃邦勇帥(原名:黃勇)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章