• 64732阅读
  • 82回复

QT自定义精美换肤界面 [复制链接]

上一主题 下一主题
离线liudianwu
 

图酷模式  只看楼主 正序阅读 楼主  发表于: 2014-08-15
— 本帖被 XChinux 执行加亮操作(2016-04-22) —
陆陆续续用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. void frmMain::mouseMoveEvent(QMouseEvent *e)
  10. {
  11.     if (mousePressed && (e->buttons() && Qt::LeftButton) && !max) {
  12.         this->move(e->globalPos() - mousePoint);
  13.         e->accept();
  14.     }
  15. }
  16. void frmMain::mousePressEvent(QMouseEvent *e)
  17. {
  18.     if (e->button() == Qt::LeftButton) {
  19.         mousePressed = true;
  20.         mousePoint = e->globalPos() - this->pos();
  21.         e->accept();
  22.     }
  23. }
  24. void frmMain::mouseReleaseEvent(QMouseEvent *)
  25. {
  26.     mousePressed = false;
  27. }

2:图形字体的使用

这里直接用的是网上的IconHelper类,也不知道最初作者是谁,反正代码也就几行,不难。
贴出CPP实现文件代码
  1. #include "iconhelper.h"
  2. IconHelper* IconHelper::_instance = 0;
  3. IconHelper::IconHelper(QObject*):
  4.     QObject(qApp)
  5. {
  6.     int fontId = QFontDatabase::addApplicationFont(":/image/fontawesome-webfont.ttf");
  7.     QString fontName = QFontDatabase::applicationFontFamilies(fontId).at(0);
  8.     iconFont = QFont(fontName);
  9. }
  10. void IconHelper::SetIcon(QLabel* lab, QChar c, int size)
  11. {
  12.     iconFont.setPointSize(size);
  13.     lab->setFont(iconFont);
  14.     lab->setText(c);
  15. }
  16. void IconHelper::SetIcon(QPushButton* btn, QChar c, int size)
  17. {
  18.     iconFont.setPointSize(size);
  19.     btn->setFont(iconFont);
  20.     btn->setText(c);
  21. }


在主窗体的构造函数中这样调用即可。
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. }



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.     ui->labInfo->setText(msg);
  16. }



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文件夹下的样式,也可以自己增加一些样式。
代码肯定还有很多不完善的地方,不能通用于任何项目,肯定需要修改不少代码才可以用于自己的项目,如果有更好的建议,非常欢迎提出来!
本站下载地址: QUI.zip (728 K) 下载次数:2710
13条评分好评度+2贡献值+2金钱+7威望+2
testuser007 金钱 +1 优秀文章,支持!n神马都是浮云 2017-10-09
永远姑娘 好评度 +1 - 2017-06-29
永远姑娘 贡献值 +1 - 2017-06-29
永远姑娘 威望 +1 - 2017-06-29
永远姑娘 金钱 +1 - 2017-06-29
hengli1982 金钱 +1 - 2017-05-18
xz199264 金钱 +1 很强大,谢谢! 2017-05-11
lin189242464 金钱 +1 - 2017-05-09
zoapk 好评度 +1 - 2017-02-11
zoapk 贡献值 +1 - 2017-02-11
12
欢迎关注微信公众号:Qt实战/Qt入门和进阶(各种开源作品、经验整理、项目实战技巧,专注Qt/C++软件开发,视频监控、物联网、工业控制、嵌入式软件、国产化系统应用软件开发) QQ:517216493  WX:feiyangqingyun  QQ群:751439350
离线aptblaze

只看该作者 82楼 发表于: 2017-10-22
离线thematic971

只看该作者 81楼 发表于: 2017-10-11
感谢无私分享 学习了
离线shepher

只看该作者 80楼 发表于: 2017-09-28
非常感谢,才转到QT来,很多东东都需要改。
有好的实例可以参照着来,快多了。
新入坑,摸索中,初步感觉挺丰腴
离线axylp123

只看该作者 79楼 发表于: 2017-06-01
感觉楼主的分享
离线xz199264

只看该作者 78楼 发表于: 2017-05-11
很强大,谢谢!
离线neversettle

只看该作者 77楼 发表于: 2017-01-14
新手膜拜
离线人间漂雪

只看该作者 76楼 发表于: 2016-07-19
谢谢大侠,受教了
离线t1029901995

只看该作者 75楼 发表于: 2016-04-21
好厉害 赞一赞
离线liudianwu

只看该作者 74楼 发表于: 2016-03-17
回 z_墨脱 的帖子
z_墨脱:[表情] 已转账 求源码学习,谢谢大神 (2016-03-17 16:59) 

已发送请查收!
欢迎关注微信公众号:Qt实战/Qt入门和进阶(各种开源作品、经验整理、项目实战技巧,专注Qt/C++软件开发,视频监控、物联网、工业控制、嵌入式软件、国产化系统应用软件开发) QQ:517216493  WX:feiyangqingyun  QQ群:751439350
离线z_墨脱

只看该作者 73楼 发表于: 2016-03-17
已转账 求源码学习,谢谢大神
离线kangsite

只看该作者 72楼 发表于: 2016-01-14
多谢

只看该作者 71楼 发表于: 2016-01-11
    
离线ddao

只看该作者 70楼 发表于: 2016-01-08
我中奖了,给我1000万!
离线yin164432843

只看该作者 69楼 发表于: 2016-01-04
终于看到,源码了,学习了!
from an
离线pamire

只看该作者 68楼 发表于: 2015-12-30
结合QSkinObject 实现的九宫格自定义窗口就好了
离线hunterzf

只看该作者 67楼 发表于: 2015-11-18
楼主,谢谢,学习一下
离线xyinfotech01

只看该作者 66楼 发表于: 2015-11-17
很好,皮肤很漂亮,学习了
离线四月逆流

只看该作者 65楼 发表于: 2015-10-22
回 aimybbe 的帖子
aimybbe:写的非常棒,我下载了你的程序,在菜单按钮上加了个Menu(setMenu)用来动态的改变样式,但是添加了按钮在setMenu之后会有一个倒着的小三角
[图片]
把按钮上的ICON就不好看了,我查阅了Qt帮助手册不知道怎么把这个小三角去掉,使用如下的样式尝试
QPushButton#btnMenu .. (2014-08-21 08:47) 

你怎么加的啊
离线crazy

只看该作者 64楼 发表于: 2015-10-22
C/C++/Qt爱好者
邮箱: kevinlq0912@163.com
公众号: devstone
博客:http://kevinlq.com/
离线seventeen

只看该作者 63楼 发表于: 2015-10-21
感谢楼主无私奉献源码,好好借鉴
离线zhuifengwy

只看该作者 62楼 发表于: 2015-10-19
回 aimybbe 的帖子
aimybbe:解决了,还是初学思维受限制啊,只要将宽度设为0px就好了,呵呵!!!
QPushButton#btnMenu::menu-indicator {
    width:0px;
....... (2014-08-21 14:00) 

非常感谢,我也是这个问题
离线凌音同学

只看该作者 61楼 发表于: 2015-10-17
感谢楼主分享
离线zhuifengwy

只看该作者 60楼 发表于: 2015-10-14
请教一下,右上角的按钮上的最大最小还有设置图标是怎么弄的 ,本人菜鸟,非常感谢
离线i_guqur

只看该作者 59楼 发表于: 2015-10-06
离线cmczgz

只看该作者 58楼 发表于: 2015-09-30
感谢楼主的无私奉献
离线liudianwu

只看该作者 57楼 发表于: 2015-09-28
新版QUI发布:
欢迎关注微信公众号:Qt实战/Qt入门和进阶(各种开源作品、经验整理、项目实战技巧,专注Qt/C++软件开发,视频监控、物联网、工业控制、嵌入式软件、国产化系统应用软件开发) QQ:517216493  WX:feiyangqingyun  QQ群:751439350
离线digitalspace

只看该作者 56楼 发表于: 2015-09-28
这么好的方法,这么好的人。
离线tyy22

只看该作者 55楼 发表于: 2015-09-23
为什么我下载下来只有1.79K    里面是空的??????????、
离线liudianwu

只看该作者 54楼 发表于: 2015-01-15
回 thewon 的帖子
thewon:各位试过没有,如果设置窗体透明属性setAttribute(Qt::WA_TranslucentBackground);最小化按钮将出现一点小毛病。具体现象就是点击最小化按钮后,然后从任务栏恢复窗口,最小化按钮的显示状态竟然是按下的,同时其它任何控件的鼠标划过样式没了。除非鼠标点击一下其它控件(特别是 .. (2015-01-15 08:54) 

那就需要在界面显示的时候重新应用样式!建议用这个http://www.qtcn.org/bbs/read-htm-tid-58060.html
欢迎关注微信公众号:Qt实战/Qt入门和进阶(各种开源作品、经验整理、项目实战技巧,专注Qt/C++软件开发,视频监控、物联网、工业控制、嵌入式软件、国产化系统应用软件开发) QQ:517216493  WX:feiyangqingyun  QQ群:751439350
离线thewon

只看该作者 53楼 发表于: 2015-01-15
各位试过没有,如果设置窗体透明属性setAttribute(Qt::WA_TranslucentBackground);最小化按钮将出现一点小毛病。具体现象就是点击最小化按钮后,然后从任务栏恢复窗口,最小化按钮的显示状态竟然是按下的,同时其它任何控件的鼠标划过样式没了。除非鼠标点击一下其它控件(特别是有样式改变的,或者有弹窗的按钮)。求解释。
本帖提到的人: @liudianwu @aimybbe
离线yesjustme1

只看该作者 52楼 发表于: 2014-12-03
楼主好认真
离线shasidaran

只看该作者 51楼 发表于: 2014-12-03
回 馒头小子 的帖子
馒头小子:为什么不能下载了啊[表情]  (2014-11-16 11:31) 

刚才也遇到下不了的问题  后来不用迅雷 ,用浏览器的下载工具下下来了
离线shasidaran

只看该作者 50楼 发表于: 2014-12-03
膜拜中,

为什么下载不下来?
离线s1021966769

只看该作者 49楼 发表于: 2014-11-29
mark
离线bubble7733

只看该作者 48楼 发表于: 2014-11-29
感谢楼主分享~
根据例子换个色系能很轻松的做出多种界面配色风格,赞!
离线llwj0303

只看该作者 47楼 发表于: 2014-11-26
顶顶顶。很好的东西,学习了
专注C++,专注Qt

只看该作者 46楼 发表于: 2014-11-24
好东西,谢谢分享
离线馒头小子

只看该作者 45楼 发表于: 2014-11-16
为什么不能下载了啊
离线weiweiqiao

只看该作者 44楼 发表于: 2014-11-15

Jobs Insanely Great.
快速回复
限100 字节
 
上一个 下一个