图标字体生成及Qt使用
1 准备
需要准备的软件
- 浏览器:用于图标的下载及图标字体的生成
- vs code:用于编辑一些文本文档
- Qt:编写程序,显示图标字体中的图标
2 图标字体的生成
2.1 准备图标
要生成图标字体,首先需要准备图标集(单个图标也没有必要生成图标字体,直接在Qt中使用就行)
以下有几个网站,可用于下载图标。关于这几个网站,详细可以去问AI,这里就不具体介绍了。笔者这里选择了第一个Remix Icon。
如下图,只下载svg即可

下载解压后,可以看到有很多文件夹,我这里将文件夹中所有的svg图标放在一个目录中

后面也可以随时补充svg图片
2.2 字体生成
打开字体生成网站,笔者这里选择IcoMoon,当然也可以选择其他的。
选择IconMoon App,进入图标字体工程界面

点击“Import”,选中所有的svg图片,然后导入

导入成功后,点击下图中右侧按钮,会弹出一个菜单,可以管理和设置这些图标的一些属性

设置成功后,点击右下角的Generate Font进入图标生成界面

此时,右下角会出现download和一个设置按钮,先点设置按钮

以下是我的配置:

设置好后,点击download下载即可。下载成功后,将压缩包解压,可以看到有以下文件

将*.ttf格式的字体文件和selection.json拷贝出来,接下来将利用selection.json文件中的信息生成字体中所有图标的地址枚举变量(C/C++)
3 生成图标地址枚举(C/C++)
接下来就需要编写Qt程序,解析json文件,生成所有图标对应地址的枚举变量,先说明下使用:
使用说明
- 首先配置ttf文件、json文件路径,以及输出路径
- 生成的枚举变量也需要进行命名,笔者这里还套了一层namespace,格式自定义就好,但一定要保留
[fill],后续[fill]将会被枚举值替换。 - 点击生成,即可生成所有图标对应的枚举信息,并且会将图标显示出来,选中图标后还会显示图标的枚举变量名和对应的地址值。

关键程序:json的解析
观察json文件就能找出下面的规律,在icons对应的jsonArray中,对于每个icon对象,有properties的对象,然后有name和code属性。name属性就是枚举名称,code属性就是地址。
{
"IcoMoonType": "selection",
"icons": [
{
"icon": {
"paths": [
"M469.333 469.333v85.333l-227.304 256h227.304v85.333h-341.333v-85.333l227.224-256h-227.224v-85.333h341.333zM896 128v85.333l-227.302 256h227.302v85.333h-341.333v-85.333l227.226-256h-227.226v-85.333h341.333z"
],
"attrs": [
{}
],
"isMulticolor": false,
"isMulticolor2": false,
"grid": 0,
"tags": [
"zzz-line"
]
},
"attrs": [
{}
],
"properties": {
"order": 4242,
"id": 0,
"name": "zzz-line",
"prevSize": 128,
"code": 62705
},
"setIdx": 0,
"setId": 0,
"iconIdx": 3057
}
],
}
下面为提取的关键代码,输入为json文件的所有内容,输出为枚举名和枚举地址,即填充[fill]中的内容。
void MainWindow::process(const QByteArray &jsonByteArray, QStringList &outList)
{
QJsonDocument doc = QJsonDocument::fromJson(jsonByteArray);
QJsonArray jsonArray = doc.object().value("icons").toArray();
auto processName = [](const QString &name){
QRegularExpression numRegex("^\\d+$");
if (numRegex.match(name).hasMatch()) {
return QString("Num0%1").arg(name);
}
// 处理非数字情况:分割连字符并转为驼峰式
QStringList parts = name.split('-', Qt::SkipEmptyParts);
QString result;
for (const QString &part : parts) {
if (!part.isEmpty()) {
// 首字母大写,其余小写
QString formatted = part.left(1).toUpper();
if (part.size() > 1) {
formatted += part.mid(1).toLower();
}
result += formatted;
}
}
return result;
};
foreach (QJsonValue value, jsonArray) {
QJsonObject rootObj = value.toObject();
QJsonObject propObj = rootObj.value("properties").toObject();
QString name = propObj.value("name").toString();
//处理名字
name = processName(name);
int addr = propObj.value("code").toInt();
QString lineStr = QString("\t%1 = 0x%2").arg(name).arg(QString::number(addr,16).toUpper());
outList.append(lineStr);
}
}
图中tabwidget中图标的显示
首先,需要将*.ttf格式的字体加入QFontDatabase中进行管理
int fontId = QFontDatabase::addApplicationFont(ttfFile);
if(fontId<0) return;
QStringList fontFamilies = QFontDatabase::applicationFontFamilies(fontId); //获取字体族 名
使用时,先设置字体,然后填入地址访问即可
QFont font;
font.setFamily(fontFamilies.at(0));
font.setPointSize(20);
//QTableWidgetItem
QTableWidgetItem *item = new QTableWidgetItem;
ui->tableWidget->setItem(i,j,item);
item->setFont(font);
item->setText(QChar(addr));
完整代码:
void MainWindow::openIcon(const QString &ttfFile, const QStringList &keyValue)
{
int fontId = QFontDatabase::addApplicationFont(ttfFile);
if(fontId<0) return;
QStringList fontFamilies = QFontDatabase::applicationFontFamilies(fontId);
ui->tableWidget->clear();
int colCount = 4;
int rowCount = keyValue.count()/colCount;
if(keyValue.count()%rowCount){
rowCount++;
}
ui->tableWidget->setColumnCount(colCount);
ui->tableWidget->setRowCount(rowCount);
// 创建字体
QFont font;
font.setFamily(fontFamilies.at(0));
font.setPointSize(20);
int count = 0;
foreach (QString key, keyValue) {
key.remove("\t");
QStringList list = key.split("=");
if(list.count()<2) continue;
QString addrStr = list.at(1);
addrStr.remove(" ");
bool ok;
int addr = addrStr.toInt(&ok,16);
if(!ok) continue;
int i = count / colCount;
int j = count % colCount;
QTableWidgetItem *item = new QTableWidgetItem;
ui->tableWidget->setItem(i,j,item);
item->setFont(font);
item->setText(QChar(addr));
key.replace("=",":");
item->setToolTip(key);
item->setData(Qt::UserRole+1,key);
count++;
}
}
图标的使用
方式1:生成QIcon
//设置字体
QFont font;
font.setFamily("XNormalIcon");
font.setPointSize(20);
//生成pixmap
QPixmap pixmap(32,32);
pixmap.fill(Qt::transparent); // 透明背景
QPainter painter(&pixmap);
painter.setFont(font);
painter.setPen(Qt::blue);
painter.drawText(pixmap.rect(), Qt::AlignCenter, QChar(SCFont::AccessibilityFill));
painter.end();
//生成icon
QIcon icon(pixmap);
方式二:对于一些可以setText的控件
先设置字体,然后setText即可
QFont font;
font.setFamily("XNormalIcon");
font.setPointSize(20);
QLabel *label = new QLabel;
label->setFont(font);
label->setText(QChar(SCFont::AccessibilityFill));

制作SVG图标字体,生成c/c++所有图标对应的枚举变量,最后在QT中使用
浙公网安备 33010602011771号