青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

逛奔的蝸牛

我不聰明,但我會很努力

   ::  :: 新隨筆 ::  ::  :: 管理 ::
1.Qt的風格
  a) Qt簡介
  Qt是一個跨平臺的C++圖形用戶界面應用程序開發庫,使用Qt可以開發出高質量的圖形用戶接口,它是完全面向對象的、易于擴展且允許真正的組件編程。Qt獲得了很大的成功,特別是它的信號-槽機制是非常值得研究的通信機制,它也是Linux發行版標準組件KDE(K Desktop Enviroment)的基礎。
  
  b) 風格機制
  Qt的風格機制實現了不同平臺上的圖形用戶接口(GUI)的觀感(look and feel),例如Windows平臺上通常使用Windows或Windows-xp風格,而Unix平臺上通常使用Motif、CDE風格。
  
  下圖顯示了Qt中與風格相關的類的繼承關系
   
  QStyle是所有風格類的基類,它控制著所有的部件(widget即windows編程中的控件)的界面風格或觀感,它定義了大量的枚舉類型和十幾個函數。枚舉類型表示界面上的不同元素(如組合框中的按鈕,按鈕的邊框等);函數控制圖形用戶界面的繪制,但大多數函數基本上只是一些聲明而沒有函數實現,他們的實現在QCommonStyle、QWindowStyle、QMotifStyle及其子類中。QStyle只實現了3個函數drawItem()," itemRect(), visualRect()。
  
  drawItem(): 負責繪制文本和象素圖。
  itemRect(): 返回文本或圖像所占的區域。
  visualRect(): 返回邏輯坐標,這個函數使Qt實現right-to-left風格(阿文、維文傳統是文本從右向左顯示,因此控件布局也是從右向左)。如下圖所示:
   
  可以看到菜單、工具條是右對齊、單選框的按鈕在右邊
  
  c)" 創建新風格的步驟
  在Qt中實現一種新風格的步驟很簡單:只需選擇一個風格類(如QCommonStyle或QStyle)作為父類,然后實現感興趣的函數即可。難點在于函數的實現。
  
  選擇父類:可以選擇QStyle, QCommonStyle, QWindowStyle, QMotifStyle以及他們的子類的任意一個作為父類。通常可以選擇QWindowsStyle或QMotifStyle,也可以選擇QCommonStyle甚至是QStyle,但是工作量會比較大,因為很多界面的細節需要自己實現。
  
  重新實現必要的函數:想修改界面風格的哪部分,就重新實現與繪制那部分相關的函數,下面解釋一下我們要重載的QStyle中的幾個函數,這幾個函數控制著圖形用戶界面上不同元素的布局和觀感。
  
             1)void drawPrimitive( PrimitiveElement pe,
             QPainter *p,
              const QRect & r,
              const QColorGroup & cg,
              SFlags flags = Style_Default,
              const QStyleOption &opt = QStyleOption::Default ) ;
              
  功能:繪制基本圖形元素,如QSpinBox中的帶箭頭的按鈕 等。
  參數:" PrimitiveElement pe: 這個枚舉型變量表示將要繪制的基本圖形界面元素(這里說的基本圖形用戶界面元素指GUI中不可再分的一個原子元素,如組合框 中的這個繪有黑色三角形的按鈕,spinBox中的按鈕 
  QPainter *p:指向QPainter類的指針,Qt中的所有繪制操作不管是繪制文本、圖形還是圖像都由這個類來處理。
  QRect &r: 表示一個矩形區域,Qt在這個區域中繪制基本界面元素(PrimitiveElement).
  QColorGroup &cg: QColorGroup表示一個部件(widget)的顏色組(color group),color group含有部件繪制自己時使用的各種顏色,譬如前景色背景色等。下圖展示了color group中的各種顏色屬性
   
  SFlags" flags: 控制如何繪制圖形界面元素的標志。
  QStyleOption &opt: 繪制不同的部件(widget)時會需要不同的參數,如繪制面板(panel)可能需要線寬作為額外參數而繪制焦點矩形(focus rect)可能需要背景色作為額外參數,所以Qt專門提供了一個類QStyleOption來封裝不同的widget可能需要的不同的參數,opt指向這樣一個類的對象。
  
  
  2)void drawComplexControl( ComplexControl control,
  QPainter *p,
  const QWidget *widget,
  const QRect &r,
  const QColorGroup &cg,
  SFlags flags = Style_Default,
  SCFlags controls = QStyle::SC_All,
  SCFlags active = QStyle::SC_None,
  const QStyleOption& opt = QStyleOption::Default)
      
  功能:繪制復雜控制部件(widget)如SpinWidget,comboBox,slider,listView等
  
  參數:
  
  ComplexControl control:是一個枚舉量,表示將要繪制的復雜控制部件(widget)如組合框、列表框等。
  QPainter *p:指向QPainter的指針,Qt中的所有繪制操作不管是繪制文本、圖形還是圖像都由這個類來處理。
  QWidget *widget:指向QWdget或其子類的指針,可以根據上面control的值轉變(cast)成合適的類型,例如如果要繪制QSpinWidget,那么control取值為CC_SpinWidget,而widget指向一個QSpinWidget(QWidget的子類)的實例(instance)。使用這個變量可以訪問QSpinWidget的成員函數和成員變量,譬如可以調用QSpinWidget的sizeHint函數獲得這個部件的缺省大小(一個矩形空間)。
  QRect &r: 表示一個矩形區域,Qt在這個區域中繪制控件或其子部件。
  QColorGroup &cg: QColorGroup表示一個部件(widget)的顏色組(color group),color group含有部件繪制自己時使用的各種顏色,譬如前景色背景色等。
  SFlags flags: 控制如何繪制圖形界面元素的標志
  SCFlags controls表示繪制復雜控制部件control的哪個子部件,缺省為SC_All,即繪制整個control而不是其某個子部件(注意control, controls是兩個不同的參數)
  QStyleOption &opt: 在繪制不同的部件時可能需要不同的額外的參數,這個變量在繪制不同的widget時提供不同的信息。
  
  
  3) QRect querySubControlMetrics(ComplexControl control,
    const QWidget* widget,
  SubControl sc,
  const QStyleOption& = QStyleOption::Default)
  
  功能:獲取子部件的坐標和尺寸信息。這個函數控制著一個復雜控件的布局,重載這個函數可以使的組合框的下拉按鈕繪制在左邊 而不是默認的右邊。
  
  參數:
  ComplexControl control: 枚舉量,表示將要繪制的復雜控制部件(widget)如組合框、列表框等。
  QWidget *widget:指向QWidget或其子類的指針,可以根據上面control的值轉變(cast)成合適的類型,例如如果要繪制QSpinWidget,那么control取值為CC_SpinWidget,而widget指向一個QSpinWidget(QWidget的子類)的實例。使用這個變量可以訪問QSpinWidget的成員函數和成員變量,譬如可以調用QSpinWidget的sizeHint函數獲得這個部件的缺省大小(一個矩形空間)。
  SubControl sc:枚舉量,一個復雜部件可能由多個的子部件組成,使用sc變量說明要獲取那個子部件的坐標和尺寸信息。
  QStyleOption &opt: 計算不同部件的尺寸時可能需要不同的額外信息,QStyleOption封裝了這些信息。
  
  2.創建新風格
  下面用一個例子來介紹一下創建新風格的整個過程,在編程之前,先看一下最終的結果是什么樣的。(在Qt內部QSpinBox類是通過QSpinWidget實現的)
  默認風格的效果: 使用新風格的效果: 
  可以看到在新風格中我們的SpinBox有了垂直顯示的效果。下面我們按上面說明的步驟來創建一種新的風格。
  
  1)選擇基類:我們選擇QWindowsStyle類作為我們新風格類的基類,當然也可以選擇QMotifStyle,在這個例子種也可以選擇QCommonStyle。一般不建議選擇QCommonStyle作為基類,因為QCommonStyle只實現了一部分界面部件,如果要實現一個完整的風格類,我們需要重新寫很多代碼。
  
  2)重載相關的函數:在這個例程中我們只修改了spinBox的風格,實現這個部件(widget)只與QStyle類的三個函數drawPrimitive, drawComplexControl, qureySubControlMerics相關,所以我們只需重載這三個函數的相關部分代碼.下面對代碼中的關鍵部分做一下注釋,不重要的部分省略了。詳細的代碼可以從后面下載。
  
  繪制spinbox中按鈕的函數:
  
  void CustomStyle::drawPrimitive( PrimitiveElement pe,
              QPainter * p,
                const QRect & r,
                const QColorGroup & cg,
                SFlags flags,
                const QStyleOption & opt ) const
  {
  /*PE_SpinWidgetUp,PE_SpinWidgetDown表示spinBox中的下按鈕和上按鈕,下面的代碼使得這兩個按鈕中的三角形分別向左和向右*/
  if ((pe == PE_SpinWidgetUp) || (pe == PE_SpinWidgetDown)){
  int fw = pixelMetric( PM_DefaultFrameWidth, 0 );//fw表示邊框寬度,默認為2
  QRect br; //spinBox上按鈕的邊界矩形不是spinBox的邊界矩形。
  br.setRect( r.x() + fw, r.y() + fw, r.width() - fw*2,
    r.height() - fw*2 );
  p->fillRect( br, cg.brush( QColorGroup::Button ) );
  int x = r.x(), y = r.y(), w = r.width(), h = r.height();
  int sw = w-4;
  int sh = sw/2 + 2;   // Must have empty row at foot of arrow
  int sx = x + w / 2 - sw / 2 - 1;
  int sy = y + h / 2 - sh / 2 - 1;
  
  QPointArray a;
  /* 設置三角形的三個點的坐標,修改這三個點可以使得QSpinBox上按鈕里的三角型呈現任意的形狀,下面的設置使得三角形表示的箭頭分別向左和向右。*/
  if ( pe == PE_SpinWidgetDown )
    a.setPoints( 3, 0, sh/2, sw-1, 1, sw-1, sh-1 );
   else
    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 
  #include 
  #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的源碼,目前對文本顯示機制只有初步了解,還沒有真正弄清,非常希望和感興趣的朋友相互交流、學習。"

轉自: http://www.lupaworld.com/?action-viewstutorial-itemid-7178
posted on 2009-09-14 07:00 逛奔的蝸牛 閱讀(7914) 評論(0)  編輯 收藏 引用 所屬分類: Qt自定義Widget
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚欧美中日韩视频| 欧美激情一二三区| 亚洲欧美日韩在线综合| 国产精品对白刺激久久久| 亚洲在线第一页| 欧美综合激情网| 亚洲国产精品va在看黑人| 欧美激情视频免费观看| 欧美伦理91| 欧美一区二区日韩一区二区| 欧美主播一区二区三区| 一区二区在线视频播放| 亚洲欧洲另类| 国产精品视频99| 免费久久99精品国产自在现线| 久久综合福利| 亚洲一区二区三区免费观看| 性欧美xxxx视频在线观看| 很黄很黄激情成人| 亚洲人成亚洲人成在线观看| 国产精品普通话对白| 久久视频在线看| 欧美久久久久久久| 久久黄色影院| 欧美久久成人| 老色批av在线精品| 欧美亚洲成人精品| 免费在线观看一区二区| 欧美日韩一级视频| 免费国产一区二区| 国产精品香蕉在线观看| 欧美成年人网| 国产精品视频你懂的| 亚洲第一福利社区| 国产亚洲欧美日韩一区二区| 亚洲三级网站| 在线观看视频欧美| 亚洲在线观看免费视频| 亚洲欧洲一区| 久久久五月天| 欧美专区第一页| 欧美日韩亚洲综合| 亚洲国产精品va在线观看黑人| 国产婷婷色综合av蜜臀av| 日韩一区二区电影网| 亚洲欧洲一区二区三区| 久久成人羞羞网站| 欧美一区二视频| 欧美天堂在线观看| 亚洲精品乱码久久久久久日本蜜臀 | 亚洲欧洲精品一区二区| 国内精品久久久久国产盗摄免费观看完整版 | 国产一区二区三区精品欧美日韩一区二区三区 | 在线免费高清一区二区三区| 亚洲一区国产| 亚洲在线不卡| 国产精品99一区二区| 亚洲人午夜精品免费| 亚洲精品国产拍免费91在线| 美女视频一区免费观看| 美女精品一区| 在线观看欧美日韩| 久久婷婷亚洲| 亚洲国产二区| 夜夜嗨av一区二区三区网页| 免费在线国产精品| 亚洲激情电影在线| 一本一本久久a久久精品综合麻豆 一本一本久久a久久精品牛牛影视 | 黑丝一区二区| 久久久www成人免费毛片麻豆| 久久精品女人| 韩国欧美一区| 久久在线视频| 91久久在线观看| 亚洲视频精品在线| 国产精品乱码久久久久久| 亚洲伊人久久综合| 久久精品国产一区二区三| 国产欧美一区二区色老头| 性做久久久久久久免费看| 久久久久久高潮国产精品视| 在线观看91精品国产麻豆| 久久夜色精品亚洲噜噜国产mv| 欧美超级免费视 在线| 亚洲精品在线免费观看视频| 欧美日韩三级视频| 亚洲欧美国产精品va在线观看 | 一区二区高清在线观看| 欧美三级电影大全| 亚洲综合久久久久| 欧美成人精品在线| 99视频在线观看一区三区| 国产精品你懂的| 久久久精品国产免大香伊| 欧美激情亚洲视频| 午夜精品久久久久久久久久久久| 韩日视频一区| 欧美日韩福利在线观看| 亚洲欧美视频一区二区三区| 欧美成人午夜77777| 亚洲自拍偷拍网址| 亚洲国产成人在线播放| 国产精品户外野外| 久久深夜福利免费观看| 9l视频自拍蝌蚪9l视频成人 | 亚洲精品国产视频| 国产精品久久久久999| 久久精品一本| 亚洲一区美女视频在线观看免费| 久久在线视频| 亚洲免费一级电影| 亚洲电影网站| 国产日韩亚洲| 欧美视频网址| 欧美成人久久| 久久全球大尺度高清视频| 中文在线资源观看视频网站免费不卡| 老鸭窝毛片一区二区三区| 亚洲综合精品自拍| 一区二区欧美视频| 亚洲国产一区视频| 激情偷拍久久| 国产一区二区成人久久免费影院| 欧美日韩视频不卡| 欧美aa国产视频| 久久久久欧美精品| 欧美一区二区三区在| 亚洲午夜激情网站| av成人动漫| 亚洲日韩欧美一区二区在线| 免费成人黄色av| 老鸭窝毛片一区二区三区| 欧美在线电影| 性欧美精品高清| 午夜视频在线观看一区二区| 亚洲天堂av电影| 亚洲午夜一区二区三区| 艳女tv在线观看国产一区| 亚洲精品三级| 亚洲精品综合在线| 亚洲精品久久久久久久久久久久| 在线观看亚洲视频啊啊啊啊| 伊人久久大香线蕉av超碰演员| 国产一区二区三区网站| 国内一区二区在线视频观看| 国产视频一区二区在线观看 | 国产一区二区高清| 国产日韩综合| 伊人精品在线| 亚洲欧洲精品一区二区三区| 亚洲人成7777| 中文av一区特黄| 亚洲自拍偷拍麻豆| 亚洲欧美国产精品va在线观看| 一区二区三区欧美激情| 亚洲一区二区三区四区视频| 亚洲综合国产| 久久久久久电影| 欧美激情二区三区| 亚洲人午夜精品免费| 一本色道久久综合精品竹菊 | 最新69国产成人精品视频免费| 亚洲国产天堂久久综合网| 亚洲精品国产精品国自产观看| 一本一本久久a久久精品牛牛影视| 一区二区三区四区五区精品| 亚洲一区二区三区色| 欧美一区二区三区在| 免费欧美在线| 国产精品嫩草影院一区二区| 激情欧美一区| 一区二区av| 久久久久久久综合日本| 亚洲电影欧美电影有声小说| 一区二区三区欧美成人| 久久av一区二区| 欧美日韩视频免费播放| 国产欧美一区二区色老头| 亚洲国产cao| 欧美一区二区黄色| 欧美激情影音先锋| 午夜国产精品影院在线观看| 欧美11—12娇小xxxx| 国产精品入口尤物| 91久久在线观看| 久久精品99无色码中文字幕 | 一本一本久久a久久精品综合妖精 一本一本久久a久久精品综合麻豆 | 一区二区三区成人| 久久久www成人免费精品| 亚洲日本电影在线| 久久精品色图| 国产精品腿扒开做爽爽爽挤奶网站| 亚洲高清毛片| 久久久精品一区| 日韩一二在线观看| 欧美freesex交免费视频| 国产欧美视频一区二区三区| 一区二区三区福利| 欧美高清视频一区二区三区在线观看| 亚洲在线观看免费视频|