QT自定义精美换肤界面
陆陆续续用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
void frmMain::mouseMoveEvent(QMouseEvent *e)
{
if (mousePressed && (e->buttons() && Qt::LeftButton) && !max) {
this->move(e->globalPos() - mousePoint);
e->accept();
}
}
void frmMain::mousePressEvent(QMouseEvent *e)
{
if (e->button() == Qt::LeftButton) {
mousePressed = true;
mousePoint = e->globalPos() - this->pos();
e->accept();
}
}
void frmMain::mouseReleaseEvent(QMouseEvent *)
{
mousePressed = false;
}
2:图形字体的使用
这里直接用的是网上的IconHelper类,也不知道最初作者是谁,反正代码也就几行,不难。
贴出CPP实现文件代码
1 #include "iconhelper.h"
2
3 IconHelper* IconHelper::_instance = ;
4 IconHelper::IconHelper(QObject*):
5 QObject(qApp)
6 {
7 int fontId = QFontDatabase::addApplicationFont(":/image/fontawesome-webfont.ttf");
8 QString fontName = QFontDatabase::applicationFontFamilies(fontId).at();
9 iconFont = QFont(fontName);
}
void IconHelper::SetIcon(QLabel* lab, QChar c, int size)
{
iconFont.setPointSize(size);
lab->setFont(iconFont);
lab->setText(c);
}
void IconHelper::SetIcon(QPushButton* btn, QChar c, int size)
{
iconFont.setPointSize(size);
btn->setFont(iconFont);
btn->setText(c);
}
在主窗体的构造函数中这样调用即可。
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), );
6 ui->btnMenu_Max->setToolTip("最大化");
7 } else {
8 location = this->geometry();
9 this->setGeometry(qApp->desktop()->availableGeometry());
IconHelper::Instance()->SetIcon(ui->btnMenu_Max, QChar(0xf079), );
ui->btnMenu_Max->setToolTip("还原");
}
max = !max;
}
3:自定义弹出信息框、询问框、错误框
我比较偷懒,直接用新建的UI窗体来实现,对信息框、询问框、错误框的判断直接在setmessage函数中处理。
1 void frmMessageBox::SetMessage(const QString &msg, int type)
2 {
3 if (type == ) {
4 ui->labIcoMain->setStyleSheet("border-image: url(:/image/info.png);");
5 ui->btnCancel->setVisible(false);
6 ui->lab_Title->setText("提示");
7 } else if (type == ) {
8 ui->labIcoMain->setStyleSheet("border-image: url(:/image/question.png);");
9 ui->lab_Title->setText("询问");
} else if (type == ) {
ui->labIcoMain->setStyleSheet("border-image: url(:/image/error.png);");
ui->btnCancel->setVisible(false);
ui->lab_Title->setText("错误");
}
ui->labInfo->setText(msg);
}
4:设置全局皮肤样式
//设置皮肤样式
static void SetStyle(const QString &styleName)
{
QFile file(QString(":/image/%1.css").arg(styleName));
file.open(QFile::ReadOnly);
QString qss = QLatin1String(file.readAll());
qApp->setStyleSheet(qss);
qApp->setPalette(QPalette(QColor("#F0F0F0")));
}
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编写可换肤的中文双拼汉字输入法
时间过得真快,不知不觉已到2015年,农历春节一眨眼就过去了,端正状态收拾心情整装待发出发. 曾经有段时间,我有一个很执着的梦想,我要导演出一部空前绝后的巨幕.不过现实无情地碾碎我的梦想,也同时将我推 ...
- qt之窗口换肤(一个qss的坑:当类属性发现变化时需要重置qss,使用rcc资源文件)
1.相关文章 Qt 资源系统qt的moc,uic,rcc命令的使用 2.概要 毕业两年了,一直使用的是qt界面库来开发程序,使用过vs08.10.13等开发工具,并安装了qt的插件,最近在做客户 ...
- qt之窗口换肤
1.相关文章 Qt 资源系统qt的moc,uic,rcc命令的使用 2.概要 毕业两年了,一直使用的是qt界面库来开发程序,使用过vs08.10.13等开发工具,并安装了qt的插件,最近在做客户 ...
- Android主题换肤 无缝切换
2016年7月6日 更新:主题换肤库子项目地址:ThemeSkinning,让app集成换肤更加容易.欢迎star以及使用,提供改进意见. 更新日志: v1.3.0:增加一键切换切换字体(初版)v1. ...
- Qt之界面换肤
简述 常用的软件基本都有换肤功能,例如:QQ.360.迅雷等.换肤其实很简单,并没有想象中那么难,利用前面分享过的QSS系列文章,沃我们完全可以实现各种样式的定制! 简述 实现原理 效果 新建QSS文 ...
- Qt编写安防视频监控系统11-动态换肤
一.前言 Qt中的动态换肤技术是非常一流的,直接调用qApp->setStyleSheet(qss);就可以对整个应用程序进行换肤,如果样式表内容不多,或者对应的贴图不对,效率还是蛮好的,不过据 ...
- atitit。gui 界面皮肤以及换肤总结 java .net c++
atitit.gui 界面皮肤以及换肤总结 java .net c++ 1. Swing 的皮肤 1 1.1. windows风格 1 1.2. Mac风格 ( liquid 框架) 1 2. 如何给 ...
- 基于QT的换肤整体解决方案(QSkinStyle)(提供Linux的XP风格)
基于QT的换肤整体解决方案(QSkinStyle) 对QT这个成功的跨平台GUI库,本身内置了对换肤功能的实现,比如cleanlooks.plastique等跨平台风格:还有一些是和平台相关的风格,比 ...
- 简单实现WPF界面控件换肤效果
效果如下如图:选择皮肤颜色 1.首先新建一个如图界面: 选择匹夫下拉框Xaml代码如下:三种颜色选项,并触发SelectionChanged事件 <ComboBox Height="2 ...
随机推荐
- MySQL5.7.10免安装版配置
最新版的 Mysql 不提供图形界面的安装了, 下载下来是一个压缩包的形式, 那么我们如何来使用它呢, 让它为我们工作呢? 环境: mysql-5.7.10-winx64 + win7(64位) 一 ...
- img外头包着a时底部出现的一小段高度的解决方法。图片水平垂直居中用css解决的方法。
<a><img/></a> 这种结构有时候在界面预览的时候会出现一段多出来的高度.这个高度,一开始我很奇怪是什么原因产生的.鼠标移动到a标签上会有高度出现,一开始我 ...
- Node.js 的初步理解
Node.js 是一个采用C++语言编写的后端的 Javascript 的运行环境, 它使用了 google 的 V8虚拟机来解释和执行代码.Node.js 的有许多有用的内置的模块,比如 http, ...
- 关于form标签,你该知道
有没有发现,自己在写模板的时候很少使用form元素,一来form和table总是那么傻傻分不清楚:二来form的特性理解不清楚,有了input.label来了直接就上,根本不用form(不知道有没有人 ...
- ASP.NET上传大文件的问题
原文:http://www.cnblogs.com/wolf-sun/p/3657241.html?utm_source=tuicool&utm_medium=referral 引言 之前使用 ...
- DIOCP之数据接收事件
一.不引用编码器与解码器的情况下(ECHO的DEMO) 类TIOCPtcpclient,接收服务器的数据事件:OnRecvBuffer 类TDiocpTcpServer,接收客户端数据事件:OnRec ...
- 问题: ActivityManager: Warning: Activity not started, its current task has been brought to the front
运行程序时看控制台有这样的错误,应用程序没跑起来. 解决办法:project-->Clean
- Fedora20安装fcitx输入法
Fedora20安装fcitx输入法 Fedora20默认安装的是ibus输入法,总有一些原因让我们选择fcitx输入法: ibus出词顺序有bug 在输入人名的时候,有些名字输入两三次后还是不会出现 ...
- widows下jieba分词的安装
在切词的时候使用到jieba分词器,安装如下: 切入到结巴包,执行 python setup.py install 安装后,可以直接在代码中引用: import jieba
- Android常见崩溃或闪退的问题描述及原因总结、及与性能相关的模块——持续更新
1.nullpointer——就是使用一个对象的时候还没有对其进行初始化导致该问题 一般在何种情况下容易出现呢? (1)父窗口+子窗口同时出现的,父窗口因为某种原因消掉了,子窗口还在,操作子窗口找不到 ...