QT自定義精美換膚界面


陸陸續續用QT開發過很多項目,也用QT寫過不少私活項目,也寫過N個工具,一直夢寐以求能像VC一樣可以很方便的有個自定義的界面,QSS的強大讓我看到了很好的希望,輾轉百度谷歌無數次,一直搜索QT相關的換膚文章,絕大部分的是一些簡單的按鈕文本樣式,要做到整體換膚程度幾乎不行,QTCN論壇里的奮斗的孩子寫了個模仿360安全衛士系列,讓我既驚喜有遺憾,驚喜的是能夠用QT實現一個這么完整的360安全衛士界面,確實不錯,也支持多種換膚,遺憾的是我下載過的是VC版本的,對於一直執着於用Qt Creator 來開發的我來說,不大喜歡,工程文件之多之復雜,對於追求精簡美的我來說更是覺得別扭,當然源碼學習參考價值還是很高的,只是個人不大喜歡而已。陸續看過slientmanQT整體換膚方案,鏈接地址:http://blog.csdn.net/slientman/article/details/5618950也從CSDN下過該可執行文件,也不知道是作者粗心還是故意,居然沒有自帶QT運行庫,導致我電腦上試過幾個版本的運行庫都不行,作者也說了,花了很多精力,不打算開源,這個對於喜歡分享的我來說,心里又是一睹,不過本人還是帶着誠意加過作者QQ,願意自費購買一套,也一直沒有得到作者的回復,有點失望。后面又在博客園里面看到24K純開源http://www.cnblogs.com/csuftzzk/)、文藝IT男(http://www.cnblogs.com/appsucc/)、 liulunhttp://www.cnblogs.com/liulun/)等幾位大俠寫過的類似工具,尤其是這篇文章(http://www.cnblogs.com/liulun/p/3775294.html)讓我認識到了還有fontawesome這個好東西,真心感謝作者!

在看過這么多習慣文章后,着手開始自己的QUI編寫過程,一開始設想的是參照這篇文章http://www.cnblogs.com/appsucc/p/3257661.html來進行開發,封裝成一個DLL,提供外部接口給需要加上皮膚的窗體調用,當開發完成之后,才發現還是會有一系列的問題,例如當主窗體需要關閉時,需調用this.parent().close()類似方法才可以關閉窗體,而且必須是QWidget才能加入到子窗體中,當有相關QDialog窗體打開需要給出返回值時,不能方便的提供done1)這樣的方法返回,后面索性拋棄了這種做法,還是采用QSS樣式調用,相關樣式都已經在樣式表中寫好,無非就五種顏色,采用了上下兩種漸變顏色,normal兩種,hover(select,focus)兩種,還有一個是文字顏色,只要將對應樣式表替換這五種顏色即可,當然大部分時候替換的是四種顏色,文字顏色默認為白色,通用絕大部分漸變顏色。 

核心處理部分:

1:無邊框窗體處理

對標題欄安裝eventFilter事件監聽器監聽鼠標雙擊事件,重載mouseMoveEventmousePressEventmouseReleaseEvent三個事件實現鼠標拖動,當窗體改變大小后還必須用QRect location;來記住當前窗體位置,方便按下右上角還原按鈕時將窗體設置在最大化前的位置。

部分代碼如下:

 1  bool frmMain::eventFilter(QObject *obj, QEvent * event)
 2 {
 3      if ( event->type() == QEvent::MouseButtonDblClick) {
 4          this->on_btnMenu_Max_clicked();
 5          return  true;
 6     }
 7      return QObject::eventFilter(obj,  event);
 8 }
 9  
10  void frmMain::mouseMoveEvent(QMouseEvent *e)
11 {
12      if (mousePressed && (e->buttons() && Qt::LeftButton) && !max) {
13          this->move(e->globalPos() - mousePoint);
14         e->accept();
15     }
16 }
17  
18  void frmMain::mousePressEvent(QMouseEvent *e)
19 {
20      if (e->button() == Qt::LeftButton) {
21         mousePressed =  true;
22         mousePoint = e->globalPos() -  this->pos();
23         e->accept();
24     }
25 }
26  
27  void frmMain::mouseReleaseEvent(QMouseEvent *)
28 {
29     mousePressed =  false;
30 }

 

2:圖形字體的使用

這里直接用的是網上的IconHelper類,也不知道最初作者是誰,反正代碼也就幾行,不難。

貼出CPP實現文件代碼

 1 #include  " iconhelper.h "
 2  
 3 IconHelper* IconHelper::_instance =  0;
 4 IconHelper::IconHelper(QObject*):
 5     QObject(qApp)
 6 {
 7      int fontId = QFontDatabase::addApplicationFont( " :/image/fontawesome-webfont.ttf ");
 8     QString fontName = QFontDatabase::applicationFontFamilies(fontId).at( 0);
 9     iconFont = QFont(fontName);
10 }
11  
12  void IconHelper::SetIcon(QLabel* lab, QChar c,  int size)
13 {
14     iconFont.setPointSize(size);
15     lab->setFont(iconFont);
16     lab->setText(c);
17 }
18  
19  void IconHelper::SetIcon(QPushButton* btn, QChar c,  int size)
20 {
21     iconFont.setPointSize(size);
22     btn->setFont(iconFont);
23     btn->setText(c);
24 }
25  

在主窗體的構造函數中這樣調用即可。

IconHelper::Instance()->SetIcon(ui->btnMenu_Close, QChar(0xf00d), 10);

右上角最大化按鈕會有兩個圖標,最大化時候一個,還原時候一個,所以這里在事件中這樣處理的。

 1  void frmMain::on_btnMenu_Max_clicked()
 2 {
 3      if (max) {
 4          this->setGeometry(location);
 5         IconHelper::Instance()->SetIcon(ui->btnMenu_Max, QChar( 0xf096),  10);
 6         ui->btnMenu_Max->setToolTip( " 最大化 ");
 7     }  else {
 8         location =  this->geometry();
 9          this->setGeometry(qApp->desktop()->availableGeometry());
10         IconHelper::Instance()->SetIcon(ui->btnMenu_Max, QChar( 0xf079),  10);
11         ui->btnMenu_Max->setToolTip( " 還原 ");
12     }
13     max = !max;
14 }
15  

3:自定義彈出信息框、詢問框、錯誤框

我比較偷懶,直接用新建的UI窗體來實現,對信息框、詢問框、錯誤框的判斷直接在setmessage函數中處理。

 1  void frmMessageBox::SetMessage( const QString &msg,  int type)
 2 {
 3      if (type ==  0) {
 4         ui->labIcoMain->setStyleSheet( " border-image: url(:/image/info.png); ");
 5         ui->btnCancel->setVisible( false);
 6         ui->lab_Title->setText( " 提示 ");
 7     }  else  if (type ==  1) {
 8         ui->labIcoMain->setStyleSheet( " border-image: url(:/image/question.png); ");
 9         ui->lab_Title->setText( " 詢問 ");
10     }  else  if (type ==  2) {
11         ui->labIcoMain->setStyleSheet( " border-image: url(:/image/error.png); ");
12         ui->btnCancel->setVisible( false);
13         ui->lab_Title->setText( " 錯誤 ");
14     }
15  
16     ui->labInfo->setText(msg);
17 }

 

4:設置全局皮膚樣式

1  // 設置皮膚樣式
2      static  void SetStyle( const QString &styleName)
3     {
4         QFile file(QString( " :/image/%1.css ").arg(styleName));
5         file.open(QFile::ReadOnly);
6         QString qss = QLatin1String(file.readAll());
7         qApp->setStyleSheet(qss);
8         qApp->setPalette(QPalette(QColor( " #F0F0F0 ")));
9     }

  

myHelper::SetStyle("black");//黑色風格

 

myHelper::SetStyle("blue");//藍色風格

myHelper::SetStyle("gray");//灰色風格

myHelper::SetStyle("navy");//天藍色風格

特點:

1:無邊框窗體,自定義標題欄,鼠標拖動,大小縮放,雙擊切換。

2:除了少量的幾個圖片資源外,幾乎使用QSS寫完所有顏色樣式控制。

3:自定義一個QMessageBox對話框,自動換行顯示提示信息,可以很方便的調用。

信息框:myHelper::ShowMessageBoxInfo

詢問框:myHelper::ShowMessageBoxQuesion

錯誤框:myHelper::ShowMessageBoxError

4:使用fontawesome圖形字體庫,將互聯網的優秀資源應用於QT中。

5:徹底公開源碼,可以任意隨意使用。

6QT各個版本都可以編譯通過,親測無誤。

7:自帶提供了四種樣式黑色、藍色、灰色、天藍色風格供選擇,可以自由更改image文件夾下的樣式,也可以自己增加一些樣式。 

代碼肯定還有很多不完善的地方,不能通用於任何項目,肯定需要修改不少代碼才可以用於自己的項目,如果有更好的建議,非常歡迎提出來! 

CSDN下載地址:http://download.csdn.net/detail/feiyangqingyun/7763413


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM