一、前言

对于众多的Qter程序员来说,美化UI一直是个老大难问题,毕竟这种事情理论上应该交给专业的美工妹妹去做,无奈在当前整体国际国内形式之下,绝大部分公司是没有专门的美工人员的,甚至说有个兼职的美工都已经是很奢侈的事情,大部分的公司都是一个程序员同时要肩负着测试员、美工人员、售后维护人员等人员的责任,老板肯定都是这么想,我花了这么多钱招你进来,所有程序相关的和周边的你都的给我搞定才行。

程序的UI美化,个人觉得就两点,第一点就是布局,你必须把控件摆整齐,一定要让用户看着舒服,而且用户操作交互方便,这点在美化UI中占比60%重要,摆的歪歪扭扭,再如何颜色牛逼图标图片牛逼也是垃圾,一看就很丑陋,就是拒绝的,你看windows系统就算没有什么鲜艳的颜色和图标,各种设置界面都是整整齐齐的,看起来就舒服,才有继续用下去的可能。第二点才是颜色和图片,颜色不知道如何配色可以去UI中国等网站找到你喜欢的界面方案,找个拾色器直接把颜色拿过来就行,图片图片就需要用到今天的主角图形字体。

图形字体的出现绝对是所有程序员的福音,各种类型的各种种类的图标应有尽有,直接找到你想要的图标按照值作为文字文本写进去就行,简直爽的不要不要的,他是作为文本的形式存在,意味着你可以任意设置大小和颜色,这就不要太强大了哇,我们需要的不就是这种效果吗?

按照这个思路,在2014年开始就封装了一个图形字体类,当初非常简单,而且重复代码非常多,今年静下心来重新封装重写了一遍,基本上形成了现在的风格,一个类同时支持多种图形字体文件(为什么有这个需求?因为网络上各种图形字体文件层出不穷,不大方便合并到一个字体文件中,而你的程序又可能都需要使用到这多个图形字体文件),全部提供静态方法设置,支持各种导航面板风格。

二、主要功能

  1. 可传入多种图形字体文件,一个类通用所有图形字体。
  2. 默认已经内置了阿里巴巴图形字体FontAliBaBa、国际知名图形字体FontAwesome、天气图形字体FontWeather。
  3. 可设置 QLabel、QAbstractButton 文本为图形字体。
  4. 可设置图形字体作为 QAbstractButton 按钮图标。
  5. 内置万能的方法 getPixmap 将图形字体值转换为图片。
  6. 无论是设置文本、图标、图片等都可以设置图标的大小、尺寸、颜色等参数。
  7. 内置超级导航栏样式设置,将图形字体作为图标设置到按钮。
  8. 支持各种颜色设置比如正常颜色、悬停颜色、按下颜色、选中颜色。
  9. 可设置导航的位置为 left、right、top、bottom 四种。
  10. 可设置导航加深边框颜色和粗细大小。
  11. 导航面板的各种切换效果比如鼠标悬停、按下、选中等都自动处理掉样式设置。
  12. 全局静态方法,接口丰富,使用极其简单方便。

三、效果图



四、开源主页

  • 以上作品完整源码下载都在开源主页,会持续不断更新作品数量和质量,欢迎各位关注。
  • 本开源项目已经成功升级到V2.0版本,分门别类,图文并茂,保你爽到爆。
  • Qt开源武林秘籍开发经验,看完学完,20K起薪,没有找我!
  1. 国内站点:https://gitee.com/feiyangqingyun/QWidgetDemo
  2. 国际站点:https://github.com/feiyangqingyun/QWidgetDemo
  3. 开源秘籍:https://gitee.com/feiyangqingyun/qtkaifajingyan
  4. 个人主页:https://qtchina.blog.csdn.net/
  5. 知乎主页:https://www.zhihu.com/people/feiyangqingyun/

五、核心代码

QPixmap IconHelper::getPixmap1(const QColor &color, int icon, quint32 size,
quint32 width, quint32 height, int flags)
{
//主动绘制图形字体到图片
QPixmap pix(width, height);
pix.fill(Qt::transparent); QPainter painter;
painter.begin(&pix);
painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
painter.setPen(color); iconFont.setPixelSize(size);
painter.setFont(iconFont);
painter.drawText(pix.rect(), flags, (QChar)icon);
painter.end();
return pix;
} void IconHelper::setStyle1(QWidget *widget, QList<QPushButton *> btns, QList<int> icons, const IconHelper::StyleColor &styleColor)
{
QList<QAbstractButton *> list;
foreach (QPushButton *btn, btns) {
list << btn;
} setStyle(widget, list, icons, styleColor);
} void IconHelper::setStyle1(QWidget *widget, QList<QToolButton *> btns, QList<int> icons, const IconHelper::StyleColor &styleColor)
{
QList<QAbstractButton *> list;
foreach (QToolButton *btn, btns) {
list << btn;
} setStyle(widget, list, icons, styleColor);
} void IconHelper::setStyle1(QWidget *widget, QList<QAbstractButton *> btns, QList<int> icons, const IconHelper::StyleColor &styleColor)
{
int btnCount = btns.count();
int iconCount = icons.count();
if (btnCount <= 0 || iconCount <= 0 || btnCount != iconCount) {
return;
} QString position = styleColor.position;
quint32 iconSize = styleColor.iconSize;
quint32 iconWidth = styleColor.iconWidth;
quint32 iconHeight = styleColor.iconHeight;
quint32 borderWidth = styleColor.borderWidth; //根据不同的位置计算边框
QString strBorder;
if (position == "top") {
strBorder = QString("border-width:%1px 0px 0px 0px;padding-top:%1px;padding-bottom:%2px;")
.arg(borderWidth).arg(borderWidth * 2);
} else if (position == "right") {
strBorder = QString("border-width:0px %1px 0px 0px;padding-right:%1px;padding-left:%2px;")
.arg(borderWidth).arg(borderWidth * 2);
} else if (position == "bottom") {
strBorder = QString("border-width:0px 0px %1px 0px;padding-bottom:%1px;padding-top:%2px;")
.arg(borderWidth).arg(borderWidth * 2);
} else if (position == "left") {
strBorder = QString("border-width:0px 0px 0px %1px;padding-left:%1px;padding-right:%2px;")
.arg(borderWidth).arg(borderWidth * 2);
} //如果图标是左侧显示则需要让没有选中的按钮左侧也有加深的边框,颜色为背景颜色
//如果图标在文字上面而设置的边框是 top bottom 也需要启用加深边框
QStringList qss;
if (styleColor.defaultBorder) {
qss << QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:solid;border-radius:0px;%2border-color:%3;color:%4;background:%5;}")
.arg(position).arg(strBorder).arg(styleColor.normalBgColor).arg(styleColor.normalTextColor).arg(styleColor.normalBgColor);
} else {
qss << QString("QWidget[flag=\"%1\"] QAbstractButton{border-style:none;border-radius:0px;padding:5px;color:%2;background:%3;}")
.arg(position).arg(styleColor.normalTextColor).arg(styleColor.normalBgColor);
} //悬停+按下+选中
qss << QString("QWidget[flag=\"%1\"] QAbstractButton:hover{border-style:solid;%2border-color:%3;color:%4;background:%5;}")
.arg(position).arg(strBorder).arg(styleColor.borderColor).arg(styleColor.hoverTextColor).arg(styleColor.hoverBgColor);
qss << QString("QWidget[flag=\"%1\"] QAbstractButton:pressed{border-style:solid;%2border-color:%3;color:%4;background:%5;}")
.arg(position).arg(strBorder).arg(styleColor.borderColor).arg(styleColor.pressedTextColor).arg(styleColor.pressedBgColor);
qss << QString("QWidget[flag=\"%1\"] QAbstractButton:checked{border-style:solid;%2border-color:%3;color:%4;background:%5;}")
.arg(position).arg(strBorder).arg(styleColor.borderColor).arg(styleColor.checkedTextColor).arg(styleColor.checkedBgColor); //窗体背景颜色+按钮背景颜色
qss << QString("QWidget#%1{background:%2;}")
.arg(widget->objectName()).arg(styleColor.normalBgColor);
qss << QString("QWidget>QAbstractButton{border-width:0px;background-color:%1;color:%2;}")
.arg(styleColor.normalBgColor).arg(styleColor.normalTextColor);
qss << QString("QWidget>QAbstractButton:hover{background-color:%1;color:%2;}")
.arg(styleColor.hoverBgColor).arg(styleColor.hoverTextColor);
qss << QString("QWidget>QAbstractButton:pressed{background-color:%1;color:%2;}")
.arg(styleColor.pressedBgColor).arg(styleColor.pressedTextColor);
qss << QString("QWidget>QAbstractButton:checked{background-color:%1;color:%2;}")
.arg(styleColor.checkedBgColor).arg(styleColor.checkedTextColor); //设置样式表
widget->setStyleSheet(qss.join("")); //可能会重复调用设置所以先要移除上一次的
for (int i = 0; i < btnCount; i++) {
for (int j = 0; j < this->btns.count(); j++) {
if (this->btns.at(j) == btns.at(i)) {
disconnect(btns.at(i), SIGNAL(toggled(bool)), this, SLOT(toggled(bool)));
this->btns.at(j)->removeEventFilter(this);
this->btns.removeAt(j);
this->pixNormal.removeAt(j);
this->pixHover.removeAt(j);
this->pixPressed.removeAt(j);
this->pixChecked.removeAt(j);
break;
}
}
} //存储对应按钮对象,方便鼠标移上去的时候切换图片
int checkedIndex = -1;
for (int i = 0; i < btnCount; i++) {
int icon = icons.at(i);
QPixmap pixNormal = getPixmap1(styleColor.normalTextColor, icon, iconSize, iconWidth, iconHeight);
QPixmap pixHover = getPixmap1(styleColor.hoverTextColor, icon, iconSize, iconWidth, iconHeight);
QPixmap pixPressed = getPixmap1(styleColor.pressedTextColor, icon, iconSize, iconWidth, iconHeight);
QPixmap pixChecked = getPixmap1(styleColor.checkedTextColor, icon, iconSize, iconWidth, iconHeight); //记住最后选中的按钮
QAbstractButton *btn = btns.at(i);
if (btn->isChecked()) {
checkedIndex = i;
} btn->setIcon(QIcon(pixNormal));
btn->setIconSize(QSize(iconWidth, iconHeight));
btn->installEventFilter(this);
connect(btn, SIGNAL(toggled(bool)), this, SLOT(toggled(bool))); this->btns << btn;
this->pixNormal << pixNormal;
this->pixHover << pixHover;
this->pixPressed << pixPressed;
this->pixChecked << pixChecked;
} //主动触发一下选中的按钮
if (checkedIndex >= 0) {
QMetaObject::invokeMethod(btns.at(checkedIndex), "toggled", Q_ARG(bool, true));
}
}

Qt开源作品43-超级图形字体的更多相关文章

  1. Qt开源作品38-无边框窗体方案(无抖动,支持win、linux、mac等系统,侧边半屏顶部全屏)

    一 前言 不知道各位程序员有没有遇到过这样一种困惑,好不容易在开源网站找到了类似的想要的项目代码,结果down下来一编译,我勒个去,几百个错误,根本没法用,熟悉的人还好可以直接阅读代码进行修改(有些只 ...

  2. 开源图形库 c语言-图形图像库 集合[转]

    开源图形库 c语言-图形图像库 集合[转] Google三维API O3D O3D 是一个开源的 Web API 用来在浏览器上创建界面丰富的交互式的 3D 应用程序.这是一种基于网页的可控3D标准. ...

  3. Github上的一些高分Qt开源项目【多图】

    游戏2D地图编辑器: 著名的TileMap编辑器,做2D游戏开发的一定不会陌生. Go 语言的IDE: Go语言的集成开发环境. Clementine Music Player: 功能很完善且跨平台支 ...

  4. NeHe OpenGL教程 第十四课:图形字体

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  5. web@css样式进阶--图形字体、动画、显隐....

    1.图形字体<i class="fa fa-heart"></i> 操作类名,需<link rel="stylesheet" hr ...

  6. Webdings 图形字体

    如果想在网页上插入图形,最简单的方式就是使用图形字体.Webdings 是一种微软开发的图形字体,在IE浏览器上可以使用它. 什么是Webdings Webdings 是一个TrueType的ding ...

  7. 我的第一个开源作品Kiwis2 Mock Server

    我的第一个开源作品Kiwis2 Mock Server,目前公测中,欢迎大家提供宝贵意见. 代码:https://github.com/kiwis2/mockserver 主页:https://kiw ...

  8. vs2008编译QT开源项目三国杀(五篇文章)

    请参看 http://tieba.baidu.com/f?kz=1508964881 按照上面的网址教程,下载三国杀源码,swig工具,并下载最新的QT4.8.2 for vs2008.我本机已经安装 ...

  9. Qt 2D绘图之六:图形视图框架的事件处理与传播

    一.简介 图形视图框架中的事件都是首先由视图进行接收,然后传递给场景,再由场景传递给相应的图形项.而对于键盘事件,它会传递给获得焦点的图形项,可以使用QGraphicsScene类的setFocusI ...

  10. Qt 2D绘图之五:图形视图框架的结构和坐标系统

    一.图形视图框架的结构 在前面讲的基本绘图中,我们可以自己绘制各种图形,并且控制它们.但是,如果需要同时绘制很多个相同或不同的图形,并且要控制它们的移动.检测它们的碰撞和叠加:或者我们想让自己绘制的图 ...

随机推荐

  1. 王树森Attention与Self-Attention学习笔记

    目录 Seq2Seq + Attention Attention的原理 方法一(Used in the original paper) 方法二(more popular,the same to Tra ...

  2. CEOI2023

    Day1 T1 A Light Inconvenience (light) 题意:若干个人排成一个队列,保证任何时刻队列中都有至少一个人.每个人手中有一个火把,火把有点亮和熄灭两种状态. 现在进行 \ ...

  3. Gitlab私有存储库支持SourceLink 调试之使用proxy方式

    前情概要 在 让你发布的nuget包支持源代码调试#为gitlab的私有源代码项目提供支持 小节中有介绍到如何让gitlab的私有存储库支持SourceLink. 其中有一个方法是说在vs中打开web ...

  4. charles+Nox

    Charles设置 一.添加SSL证书 ![1](C:\Users\Lifree\Desktop\MD\C\charles zhengshu\1.png) ![2](C:\Users\Lifree\D ...

  5. 相机系统 GLFW OPENGL

    目录 0. 前言 1. 世界坐标系 2. GLFW 窗口坐标系 与 坐标系变换 3. 相机是什么东西 4. 相机的平面位移(上下左右) 5. 相机的聚焦点环绕(球形环绕 ArcBall Orbit) ...

  6. 安装了多个python版本指定pip安装目录

    #检查库安装的目录import os import numpy as np import pandas as pd print(os.path.dirname(np.__file__)) print( ...

  7. Hugging Face 与 TruffleHog 合作,实现风险预警

    我们非常高兴地宣布与 Truffle Security 建立合作伙伴关系并在我们的平台集成 TruffleHog 强大的风险信息扫描功能.这些特性是 我们持续致力于提升安全性 的重要举措之一. Tru ...

  8. Maxima 使用教程

    说起数学软件,我们很多人脑子里浮现出的第一个就是 matlab,不可否认,matlab 确实是一个优秀的数学软件,但是它需要付费啊(这里不讨论盗版问题).那么有没有一个同样强大但免费的数学软件呢?答案 ...

  9. PCI-5565-反射内存RFM2G的学习与使用

    1.介绍 反射内存集成在反射内存卡上,我们使用的是PCI总线的反射内存卡PCI5565,还有PCIE和其它总线类型的反射内存卡,原理差不多.在两台计算机的PCI插槽插两块反射内存卡,然后通过光纤连接. ...

  10. Quartz集群增强版_00.How to use?(如何使用)

    Quartz集群增强版_00.How to use?(如何使用) 转载请著名出处 https://www.cnblogs.com/funnyzpc/p/18540378 开源地址 https://gi ...