陆陆续续用QT开发过很多项目,也用QT写过不少私活项目,也写过N个工具,一直梦寐以求能像VC一样可以很方便的有个自定义的界面,QSS的强大让我看到了很好的希望,辗转百度谷歌无数次,一直搜索QT相关的换肤文章,绝大部分的是一些简单的按钮文本样式,要做到整体换肤程度几乎不行,QTCN论坛里的奋斗的孩子写了个模仿360安全卫士系列,让我既惊喜有遗憾,惊喜的是能够用QT实现一个这么完整的360安全卫士界面,确实不错,也支持多种换肤,遗憾的是我下载过的是VC版本的,对于一直执着于用Qt Creator 来开发的我来说,不大喜欢,工程文件之多之复杂,对于追求精简美的我来说更是觉得别扭,当然源码学习参考价值还是很高的,只是个人不大喜欢而已。陆续看过slientman的QT整体换肤方案,链接地址:http://blog.csdn.net/slientman/article/details/5618950也从CSDN下过该可执行文件,也不知道是作者粗心还是故意,居然没有自带QT运行库,导致我电脑上试过几个版本的运行库都不行,作者也说了,花了很多精力,不打算开源,这个对于喜欢分享的我来说,心里又是一睹,不过本人还是带着诚意加过作者QQ,愿意自费购买一套,也一直没有得到作者的回复,有点失望。后面又在博客园里面看到24K纯开源(http://www.cnblogs.com/csuftzzk/)、文艺IT男(http://www.cnblogs.com/appsucc/)、 liulun(http://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窗体打开需要给出返回值时,不能方便的提供done(1)这样的方法返回,后面索性抛弃了这种做法,还是采用QSS样式调用,相关样式都已经在样式表中写好,无非就五种颜色,采用了上下两种渐变颜色,normal两种,hover(select,focus等)两种,还有一个是文字颜色,只要将对应样式表替换这五种颜色即可,当然大部分时候替换的是四种颜色,文字颜色默认为白色,通用绝大部分渐变颜色。
核心处理部分:
1:无边框窗体处理
对标题栏安装eventFilter事件监听器监听鼠标双击事件,重载mouseMoveEvent、mousePressEvent、mouseReleaseEvent三个事件实现鼠标拖动,当窗体改变大小后还必须用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:彻底公开源码,可以任意随意使用。
6:QT各个版本都可以编译通过,亲测无误。
7:自带提供了四种样式黑色、蓝色、灰色、天蓝色风格供选择,可以自由更改image文件夹下的样式,也可以自己增加一些样式。
代码肯定还有很多不完善的地方,不能通用于任何项目,肯定需要修改不少代码才可以用于自己的项目,如果有更好的建议,非常欢迎提出来!
CSDN下载地址:http://download.csdn.net/detail/feiyangqingyun/7763413
分类: Qt学习
标签: QT, 换肤
好文要顶 关注我 收藏该文
飞扬青云
关注 - 6
粉丝 - 364
+加关注
23
0
« 上一篇:QT编写DLL给外部程序调用,提供VC/C#/C调用示例(含事件)
» 下一篇:年底奉献-QT编写视频监管平台(开源)
posted @ 2014-08-15 20:47 飞扬青云 阅读(59206) 评论(33) 编辑 收藏
评论列表
#1楼 2014-08-15 21:00 无色
为什么不用qml,还支持动画,要什么qq,360界面,就看会不会美工,会不会去logo。
支持(0)反对(0)
#2楼 2014-08-15 21:47 jeffreywu
不错啊,MARK.
支持(0)反对(0)
#3楼 2014-08-16 09:19 24K纯开源
不错,不过有点问题,按钮上总会有一点虚线框,影响美感!
支持(0)反对(0)
#4楼 2014-08-16 09:38 Virson Ma
很好的文章,赞一个!
支持(0)反对(0)
#5楼 2014-08-16 09:39 GoYF
用WPF来实现很容易的啊
支持(0)反对(0)
#6楼[楼主] 2014-08-16 13:00 飞扬青云
@ 24K纯开源
设置为nofocus就行!我个人还是喜欢下面的按钮这个虚边框,因为可以用tab键切换,如果设置为nofocus的话就不能使用键盘控制焦点了,所以没有去掉,不过右上角的四个按钮(菜单、最小化、最大化、关闭)是设置的nofocus没有虚边框的!
支持(0)反对(0)
#7楼[楼主] 2014-08-16 13:01 飞扬青云
@ Go远方
我主要做的是ARM上的程序开发,用WPF无能为力!
支持(0)反对(0)
#8楼[楼主] 2014-08-16 13:02 飞扬青云
@ 无色
目前还不会qml,让你见笑了!
支持(0)反对(0)
#9楼[楼主] 2014-08-16 13:02 飞扬青云
@ codepat
谢谢支持
支持(0)反对(0)
#10楼[楼主] 2014-08-16 13:02 飞扬青云
@ Virson Ma
谢谢兄弟支持
支持(0)反对(0)
#11楼 2014-08-16 13:23 我不清楚是谁
那就不是个事!
支持(0)反对(0)
#12楼 2014-08-16 16:32 pandaren
晕 不怎么登csdn啊 10分啊
支持(0)反对(0)
#13楼 2014-08-16 16:56 PBER
写的太好了
支持(0)反对(0)
#14楼 2014-08-17 13:53 癫疯80后
CSDN分不够啊。
支持(0)反对(0)
#15楼 2014-08-17 21:25 卡卡西村长
写得很好!我以前也写过,EasyComic就是用QT实现的,支持换肤,http://www.easycomic.net。
基本思路如下:
1、窗口非客户区是个难题,不能拦截非客户区消息去重画,那样就做不到跨平台了。所以,只能设置无边框的窗体,然后放控件,或者重画。
2、系统自带的MessageBox、PrintDialog、OpenFileDialog等对话框,需要自己重新实现。
3、剩下都能通过QSS实现,QSS还是非常强大的。
支持(4)反对(0)
#16楼 2014-08-17 21:28 Wei丶Haijun
mark,挺不错的。
支持(0)反对(0)
#17楼 2014-08-18 08:03 XiaoFaye
太牛了,支持!!!
支持(0)反对(0)
#18楼 2014-08-18 08:23 程序诗人
mark
支持(0)反对(0)
#19楼 2014-08-18 08:49 EcitGis
mark
支持(0)反对(0)
#20楼 2014-08-18 09:28 草原奔马
牛人,支持!!
支持(0)反对(0)
#21楼[楼主] 2014-08-18 09:40 飞扬青云
支持(0)反对(0)
#22楼[楼主] 2014-08-18 10:37 飞扬青云
@ Lave Zhang
使用了下QEasyComic,界面上简直是超凡脱俗,一级棒,功能上也是顶呱呱!是我见过的用QT写的最好的软件了!彻底膜拜大侠!
支持(0)反对(0)
#23楼 2014-08-18 11:44 wakasann
mark
支持(0)反对(0)
#24楼 2014-08-18 12:32 卡卡西村长
@ 飞扬青云
谢谢,过奖了,我用QT也才1年多,大家可以多多交流^_^
EasyComic是一款免费的漫画制作软件,还在不断升级中,屌丝们可以用来快速制作漫画,也可以做一些简单的矢量平面设计。
支持(1)反对(0)
#25楼 2014-08-18 15:17 customevalidator
@ Lave Zhang
大赞
支持(0)反对(0)
#26楼 2014-08-18 16:07 EcitGis
mark
支持(0)反对(0)
#27楼 2014-12-22 16:42 Viro Yiheng
mark
支持(0)反对(0)
#28楼 2015-02-04 12:29 MDGSF
可以发一份给我么?
不知道为什么csdn下载的一直都没办法下载下来。
[email protected]
谢谢!!
支持(0)反对(0)
#29楼 2015-02-11 13:33 架构师米洛
非常好的代码,MARK
支持(0)反对(0)
#30楼 2015-10-05 23:23 代码苦行僧
膜拜大牛
支持(0)反对(0)
#31楼 2015-12-17 16:24 hoodlum1980
@ Lave Zhang
你的软件做的挺好。
支持(0)反对(0)
#32楼 2017-10-11 09:02 结尾。
大牛 求源码 没有积分呐
支持(0)反对(0)
#33楼 2017-10-11 09:02 结尾。
[email protected] 求 源码 膜拜大牛
支持(0)反对(0)
刷新评论刷新页面返回顶部
注册用户登录后才能发表评论,请 登录 或 注册,访问网站首页。
【推荐】超50万VC++源码: 大型组态工控、电力仿真CAD与GIS源码库!
【前端】SpreadJS表格控件,可嵌入应用开发的在线Excel
【推荐】如何快速搭建人工智能应用?
【活动】AI技术全面场景化落地实践
【大赛】2018首届“顶天立地”AI开发者大赛
最新IT新闻:
· 谷歌亚马逊微软抢食美军AI大单 胜者将独霸未来十年
· 谷歌为什么要对Android的开源严防死守?
· 如何做出一块抗造的手机屏?康宁大猩猩玻璃背后的故事
· 网易云发布开源私有云“瀚海”及云计算全栈一体机
· 杭州现共享单车"坟场" 被"肢解"单车随处可见
» 更多新闻...
最新知识库文章:
· 历史转折中的“杭派工程师”
· 如何提高代码质量?
· 在腾讯的八年,我的职业思考
· 为什么我离开了管理岗位
· 那些让人睡不着觉的bug,你有没有遭遇过?
» 更多知识库文章...
核心处理部分: 1:无边框窗体处理 对标题栏安装eventFilter事件监听器监听鼠标双击事件,重载mouseMoveEvent、mousePressEvent、mouseReleaseEvent三个事件实现鼠标拖动,当窗体改变大小后还必须用QRect location;来记住当前窗体位置,方便按下右上角还原按钮时将窗体设置在最大化前的位置。 部分代码如下: 1 bool frmMain::eventFilter(QObject *obj, QEvent *event)
2:图形字体的使用 这里直接用的是网上的IconHelper类,也不知道最初作者是谁,反正代码也就几行,不难。 贴出CPP实现文件代码 1 #include "iconhelper.h" 在主窗体的构造函数中这样调用即可。 IconHelper::Instance()->SetIcon(ui->btnMenu_Close, QChar(0xf00d), 10); 右上角最大化按钮会有两个图标,最大化时候一个,还原时候一个,所以这里在事件中这样处理的。 1 void frmMain::on_btnMenu_Max_clicked() 3:自定义弹出信息框、询问框、错误框 我比较偷懒,直接用新建的UI窗体来实现,对信息框、询问框、错误框的判断直接在setmessage函数中处理。 1 void frmMessageBox::SetMessage(const QString &msg, int type)
4:设置全局皮肤样式 1 //设置皮肤样式
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:彻底公开源码,可以任意随意使用。 6:QT各个版本都可以编译通过,亲测无误。 7:自带提供了四种样式黑色、蓝色、灰色、天蓝色风格供选择,可以自由更改image文件夹下的样式,也可以自己增加一些样式。 代码肯定还有很多不完善的地方,不能通用于任何项目,肯定需要修改不少代码才可以用于自己的项目,如果有更好的建议,非常欢迎提出来! CSDN下载地址:http://download.csdn.net/detail/feiyangqingyun/7763413 |
||||||
Copyright ©2018 飞扬青云