http://www.qtcn.org/bbs/read-htm-tid-57229.html
陆陆续续用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; 来记住当前窗体位置,方便按下右上角还原按钮时将窗体设置在最大化前的位置。
部分代码如下:
- bool frmMain::eventFilter(QObject *obj, QEvent *event)
- {
- if (event->type() == QEvent::MouseButtonDblClick) {
- this->on_btnMenu_Max_clicked();
- return true;
- }
- return QObject::eventFilter(obj, event);
- }
- 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 实现文件代码
- #include "iconhelper.h"
- IconHelper* IconHelper::_instance = 0;
- IconHelper::IconHelper(QObject*):
- QObject(qApp)
- {
- int fontId = QFontDatabase::addApplicationFont(":/image/fontawesome-webfont.ttf");
- QString fontName = QFontDatabase::applicationFontFamilies(fontId).at(0);
- 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);
右上角最大化按钮会有两个图标,最大化时候一个,还原时候一个,所以这里在事件中这样处理的。
- void frmMain::on_btnMenu_Max_clicked()
- {
- if (max) {
- this->setGeometry(location);
- IconHelper::Instance()->SetIcon(ui->btnMenu_Max, QChar(0xf096), 10);
- ui->btnMenu_Max->setToolTip("最大化");
- } else {
- location = this->geometry();
- this->setGeometry(qApp->desktop()->availableGeometry());
- IconHelper::Instance()->SetIcon(ui->btnMenu_Max, QChar(0xf079), 10);
- ui->btnMenu_Max->setToolTip("还原");
- }
- max = !max;
- }
3 :自定义弹出信息框、询问框、错误框
我比较偷懒,直接用新建的 UI 窗体来实现,对信息框、询问框、错误框的判断直接在 setmessage 函数中处理。
- void frmMessageBox::SetMessage(const QString &msg, int type)
- {
- if (type == 0) {
- ui->labIcoMain->setStyleSheet("border-image: url(:/image/info.png);");
- ui->btnCancel->setVisible(false);
- ui->lab_Title->setText("提示");
- } else if (type == 1) {
- ui->labIcoMain->setStyleSheet("border-image: url(:/image/question.png);");
- ui->lab_Title->setText("询问");
- } else if (type == 2) {
- 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");// 黑色风格
![](https://i-blog.csdnimg.cn/blog_migrate/eac1e5577930066cd064192e84b16b96.jpeg)
![](https://i-blog.csdnimg.cn/blog_migrate/23f50d5d668455be0c2e691ffd0d0ca4.jpeg)
myHelper::SetStyle("gray");// 灰色风格
![](https://i-blog.csdnimg.cn/blog_migrate/7d1f3e5cff0c0665b9acad399973079c.jpeg)
myHelper::SetStyle("navy");// 天蓝色风格
![](https://i-blog.csdnimg.cn/blog_migrate/82caa32ad3819beabf55a267eafb9c3c.jpeg)
特点:
1 :无边框窗体,自定义标题栏,鼠标拖动,大小缩放,双击切换。
2 :除了少量的几个图片资源外,几乎使用 QSS 写完所有颜色样式控制。
3 :自定义一个 QMessageBox 对话框,自动换行显示提示信息,可以很方便的调用。
信息框: myHelper::ShowMessageBoxInfo
询问框: myHelper::ShowMessageBoxQuesion
错误框: myHelper::ShowMessageBoxError
4 :使用 fontawesome 图形字体库,将互联网的优秀资源应用于 QT 中。
5 :彻底公开源码,可以任意随意使用。
6 : QT 各个版本都可以编译通过,亲测无误。
7 :自带提供了四种样式黑色、蓝色、灰色、天蓝色风格供选择,可以自由更改 image 文件夹下的样式,也可以自己增加一些样式。
代码肯定还有很多不完善的地方,不能通用于任何项目,肯定需要修改不少代码才可以用于自己的项目,如果有更好的建议,非常欢迎提出来!
本站下载地址: QUI.zip (728 K) 下载次数:890
信息框:myHelper::ShowMessageBoxInfo
询问框:myHelper::ShowMessageBoxQuesion
错误框:myHelper::ShowMessageBoxError