?? qianb.txt
字號:
a.setPoints( 3, 0, 1, 0, sh-1, sw-1, sh/2 );
...........
p->drawPolygon( a ); //繪制三角形
}else if((pe == PE_ButtonBevel) || (pe == PE_ButtonCommand) || (pe == PE_ButtonTool)
|| (pe == PE_ButtonDropDown) || (pe == PE_HeaderSection))
{ //繪制按鈕的各種效果使得看起來凸起或凹下。
qDrawShadePanel(p, r, cg, flags & (Style_Sunken | Style_Down | Style_On),
1, &cg.brush(QColorGroup::Button));
}else{
/*對于其他基本圖形元素(PrimitiveElement)的繪制我們不作處理只是簡單的調用父類的函數。*/
QWindowsStyle::drawPrimitive( pe, p, r, cg, flags, opt);
}
}
繪制整個spinBox的函數:
void CustomStyle::drawComplexControl( ComplexControl control,
QPainter *p,
const QWidget *widget,
const QRect &r,
const QColorGroup &cg,
SFlags flags,
SCFlags controls,
SCFlags active,
const QStyleOption& opt ) const
{
//下面的代碼使得spinWidget呈現垂直顯示的風格而不是通常的水平顯示
if (control == CC_SpinWidget) {
const QSpinWidget * sw = (const QSpinWidget *) widget;
//繪制向上按鈕部分,controls默認為SC_All,即繪制整個spinwidget
if ( controls & SC_SpinWidgetUp ) {
if ( sw->buttonSymbols() == QSpinWidget::PlusMinus )
pe = PE_SpinWidgetPlus; // 使用加減號
else
pe = PE_SpinWidgetUp; // 使用三角形
QRect re = sw->upRect();
QColorGroup ucg = sw->isUpEnabled() ? cg : sw->palette().disabled();
drawPrimitive(PE_ButtonBevel, p, re, ucg, flags); //繪制按鈕的邊框
drawPrimitive(pe, p, re, ucg, flags); //繪制按鈕
}
//繪制向左按鈕部分。
if ( controls & SC_SpinWidgetDown ) {
/*與繪制向下按鈕相似*/
}
}else{//不處理spinbox之外的其他復雜控制部件,調用父類函數處理
QWindowsStyle::drawComplexControl(control, p, widget, r, cg, flags, controls, active, opt);
}
}
獲取部件(widget)中各個子部件布局信息的函數,這個函數控制著一個widget的外觀
QRect CustomStyle::querySubControlMetrics( ComplexControl control,
const QWidget *widget,
SubControl sc,
const QStyleOption &opt ) const
{
if(control == CC_SpinWidget){
int fw = pixelMetric( PM_SpinBoxFrameWidth, widget);
/*QSize 定義二維對象的大小,也就是寬和高. 坐標類型是QCOORD定義為int)*/
QSize bs; //此處bs表示每個按鈕的大小,因為有兩個按鈕所以下面除以2.
bs.setWidth(widget->width()/2 -fw);
if(bs.width() < 8) bs.setWidth(8);
/*按鈕高度設置為QMIN{按鈕寬度的1.6倍, 部件高度的四分之一}
bs.setHeight( QMIN(bs.width()*8/5, widget->height() / 4) );
bs = bs.expandedTo( QApplication::globalStrut() );
int x = fw;
int y, ly, ry;
y = widget->height() - x - bs.height();
ly = fw;
ry = y - fw;
//下面定義了QSpinWidget的各個子部件的坐標位置.
switch ( sc ) {
case SC_SpinWidgetUp:
//返回向右按鈕的坐標信息
return QRect(x + bs.width(), y, bs.width(), bs.height());
case SC_SpinWidgetDown:
//返回向左按鈕的坐標信息
return QRect(x, y, bs.width(), bs.height());
case SC_SpinWidgetButtonField:
//返回兩個按鈕的總區域大小
return QRect(x, y, widget->width() - 2*fw, bs.height());
case SC_SpinWidgetEditField:
/*返回可編輯框的坐標信息*/
return QRect(fw, ly, widget->width() - 2*fw, ry);
case SC_SpinWidgetFrame:
//返回整個spinBox的坐標信息
return widget->rect();
default:
break;
}
}else{//其它部件的布局信息調用父類的函數來處理。
return QWindowsStyle::querySubControlMetrics(control,widget,sc,opt );
}
return QRect();
}
3.使用新風格
有兩種方法使用新風格,一種是作為插件,一種是在應用程序里直接使用。作為插件的風格可以在不用修改代碼、不用重新編譯的情況下使用新風格。由于本文著重介紹如何創建風格所以我們使用第一種方法。這種方法很簡單,只需在應用程序中包含相應風格類的頭文件,然后把main()函數第一句可執行代碼設置為 QApplication::setStyle(new MyStyle())即可。
下面我們用一個小例子來看看效果。
#include <qapplication.h>
#include <qspinbox.h>
#include "customstyle.h"
int main( int argc, char **argv )
{
QApplication::setStyle(new CustomStyle()); //使用新風格類來繪制界面。
QApplication a( argc, argv );
QSpinBox spin( 0, 15 );
spin.resize( 20, 100 );
a.setMainWidget( &spin );
spin.show();
return a.exec();
}
然后編譯運行即可看到效果。
Ps. qt中編譯使用qmake,步驟為
創建源程序
同一目錄下運行qmake -project
qmake
make
運行可執行程序。
4.進一步工作
1)默認大小:細心的朋友可能看到上面的代碼中有一句:spin.resize( 20, 100 ),這一句設置spinbox的長度為20象素,寬度為100個象素。如果沒有這一句的話,顯示的結果會一團糟,兩個按鈕幾乎看不到
,因為qt默認的顯示是水平顯示而根本沒有考慮垂直顯示的情況。
如果想讓spinbox在默認情況下看起來長度窄而寬度高需要修改QSpinBox類中的sizeHint函數,這個函數功能是設置部件(widget)的默認尺寸。在qt中幾乎每個GUI部件類都有sizeHint這個函數來設置它自己的默認的長和寬。
文本垂直顯示:在此例中雖然控件spinbox達到了垂直顯示的效果,但是文本仍舊是水平顯示的,因此要達到真正的垂直顯示需要了解qt的文本顯示機制。這些工作是很有意義的,因為有些民族(如蒙文)的語言傳統就是垂直顯示的,而現在沒有一個真正滿足這種需求的系統。筆者現在正在看qt-x11-free- 3.2.2的源碼,目前對文本顯示機制只有初步了解,還沒有真正弄清,非常希望和感興趣的朋友相互交流、學習。
參考資料
實例 源代碼下載
Qt官方文檔 http://doc.trolltech.com/3.2/index.html
Qt源代碼:QStyle, QCommonStyle,QSpinWidget,QSpinBox從中可以了解很多的細節.
關于作者
姚延棟:中國科學院軟件所2002級研究生,方向為系統軟件和中文信息處理,對復雜文本處理和系統編程(Qt, Gtk等)很感興趣,聯系方式: ydyao@mails.gscas.ac.cn
對本文的評價
您對這篇文章的看法如何?
太差! (1) 需提高 (2) 一般;尚可 (3) 好文章 (4) 真棒!(5)
建議?
developerWorks 中國 > Linux >
關于 IBM 隱私條約 聯系 IBM
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -