Qt5.6.1如何使用qpf2字体
最近在移植Qt到一个商用的小众系统上,Qt版本是Qt5.6.1,Qt是不支持这个系统的,在移植过程中遇到了很多的问题,这里对字体移植遇的问题进行一下记录。(这个办法是可以使用qpf2字体的,但是是不是最好的办法还不知道,希望可以帮助到需要的人,也希望有人一起讨论)
1.问题:
首先是报找不到字体,当字体的路径设置正确后。程序在调用setText相关方法的时候,整个系统就会dump掉,这个系统经常用dump,内存分配上可能有一些问题。如果字体的路径设置不正确系统倒是可以正确运行,最后经过查找代码和参考网上的经验决定使用qpf字体(优点就是省去了Qt解析字体这个过程,占用内存小(我怀疑系统dump是存上有问题),缺点是qpf字体字号大小是固定的,他是一个二进制的文件)。
2.进展:
Qt Help文档说明Qt是支持qpf字体的,在Qt4版本之后支持qpf2字体。把字库下的所有字体删除只留下qpf2字体还是没有办法显示(在PC机上和目标板上尝试都是不可以的)。在网上查到资料说是Qt5虽然说是支持qpf2,但是实际上是个BUG,实现根本不支持(我查看代码后发现,是一个虚函数,当调用子类的方法时就不支持qpf2,当调用父类的方法时就支持qpf2,下面会说一下这个问题),没有找到解决办法。
于是查看源码和PC跟踪程序执行过程。
3.解决:
在字体相关初始化的过程中会调用qt-everywhere-opensource-src-5.6.1\qtbase\src\platformsupport\fontdatabases\fontconfig\qfontconfigdatabase.cpp文件中的
initializeDb()方法
源码如下:
static void initializeDb()
{
QFontDatabasePrivate *db = privateDb();
// init by asking for the platformfontdb for the first time or afterinvalidation
if (!db->count)
QGuiApplicationPrivate::platformIntegration()->fontDatabase()->populateFontDatabase();
if (db->reregisterAppFonts) {
for (int i = 0; i < db->applicationFonts.count(); i++) {
if (!db->applicationFonts.at(i).families.isEmpty())
registerFont(&db->applicationFonts[i]);
}
db->reregisterAppFonts = false;
}
}
populateFontDatabase()这个方法有两处实现分别见下面的源码,而initializeDb()方法中调用的实际是populateFontDatabase();方法实现际调用的是QBasicFontDatabase类中实现的。
qtbase/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp中
和
qtbase/src/gui/text/qplatformfontdatabase.cpp中
在类QBasicFontDatabase定义中可以看到QBasicFontDatabase是QPlatformFontDatabase子类
class QBasicFontDatabase : publicQPlatformFontDatabase
{
public:
// void populateFontDatabase() Q_DECL_OVERRIDE; //change on_ose
/* QFontEngine *fontEngine(const QFontDef &fontDef, void *handle)Q_DECL_OVERRIDE;
QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize,QFont::HintingPreference hintingPreference) Q_DECL_OVERRIDE;
QStringList addApplicationFont(const QByteArray &fontData, constQString &fileName) Q_DECL_OVERRIDE;
void releaseHandle(void *handle) Q_DECL_OVERRIDE;
static QStringList addTTFile(const QByteArray &fontData, constQByteArray &file);
*/
};
下面给出QBasicFontDatabase和QPlatformFontDatabase类中populateFontDatabase()方法的实现:
1.
voidQBasicFontDatabase::populateFontDatabase()
{
QString fontpath = fontDir();
QDir dir(fontpath);
if (!dir.exists()) {
qWarning("QFontDatabase: Cannot find font directory %s - is Qtinstalled correctly?",
qPrintable(fontpath));
return;
}
QStringList nameFilters;
nameFilters << QLatin1String("*.ttf")
<< QLatin1String("*.ttc")
<<QLatin1String("*.pfa")
<<QLatin1String("*.pfb")
<<QLatin1String("*.otf");
foreach (const QFileInfo &fi, dir.entryInfoList(nameFilters,QDir::Files)) {
const QByteArray file = QFile::encodeName(fi.absoluteFilePath());
QBasicFontDatabase::addTTFile(QByteArray(), file);
}
}
2.
voidQPlatformFontDatabase::populateFontDatabase()
{
QString fontpath = fontDir();
if(!QFile::exists(fontpath)) {
qWarning("QFontDatabase: Cannot find font directory '%s' - is Qtinstalled correctly?",
qPrintable(QDir::toNativeSeparators(fontpath)));
return;
}
QDir dir(fontpath);
dir.setNameFilters(QStringList() <<QLatin1String("*.qpf2"));
dir.refresh();
for (int i = 0; i < int(dir.count()); ++i) {
const QByteArray fileName =QFile::encodeName(dir.absoluteFilePath(dir[i]));
QFile file(QString::fromLocal8Bit(fileName));
if (file.open(QFile::ReadOnly)) {
const QByteArray fileData = file.readAll();
QByteArray *fileDataPtr = new QByteArray(fileData);
registerQPF2Font(fileData, fileDataPtr);
}
}
}
从两个类的方法中可以看到QBasicFontDatabase::populateFontDatabase()中是在对ttf等字体进行加载。而QPlatformFontDatabase::populateFontDatabase()中是对qpf2字体进行加载。所以这就解释了为什么Qt5.6.1不能使用qpf2字体。这个加载qpf2字体的方法没有被调用啊。肯定怎么也支持不了qpf2。所以果断的将QBasicFontDatabase这个类相关的文件注释掉(这样程序在运行的时候就自动调用了父类也就是QPlatformFontDatabase::populateFontDatabase()方法,这个方法是个虚函数)。这里包括qbasicfontdatabase_p.h中QBasicFontDatabase类的定义和qbasicfontdatabase.cpp整个文件的内容(#if 0 .......#endif即可)。
重新编译Qt源码,将qpf2文件放在字体目录下(lib/fonts/dejavu_sans_11_50.qpf2)。开机运行生程序可显示字符不dump掉了。剩下的工作就是制作字体了。
Qt5.6.1如何使用qpf2字体相关推荐
- Linux QT5.12 一种整体界面字体设置的方法及设置PlainTextEdit组件的字体大小方法
1.在Linux QT5.12开发界面时,经常会涉及到界面字体大小的设置,默认字体一般比较小,解决方法如下: 在main函数中添加代码: //============================= ...
- qt 字体不随dpi_Windows – QT5字体渲染在各种平台上不同
我想对某些自定义小部件渲染进行可重复的测试.为了做到这一点,我将它们绘制成一个Q Image,并将结果保存为PNG.与MacOSX相比,Windows的输出真的不同. 我照顾: >在所有平台上选 ...
- qt程序在Linux下字体乱了,QT5程序字体渲染的问题
因为不断现代化的Linux系统再也无法调用infinality渲染包中的/etc/profile.d/infinality-settings.sh脚本,所以写在这个脚本里的系统字体全局参数已失效: X ...
- Qt-5.5.1 设置界面字体为微软雅黑
Qt界面默认字体都很丑,于是想自己安装微软雅黑字体. 安装环境:Ubuntu 14.04 Qt-5.5.1 1.下载微软雅黑字体: 可以从下面的链接下载,也可以自己百度下载:http://ht ...
- 【Qt教程】1.11 - Qt5 标准对话框QMessageBox(关于、错误、信息、警告、问题、颜色、字体、文件对话框)
所谓标准对话框,是Qt内置的一些列对话框,用于简化开发.其实是调用的系统窗口.事实上,有很多对话框都是通用的,比如打开文件.设置颜色.打印设置等.这些对话框在素有程序中几乎相同,因此没有必要在每一个程 ...
- QT5.9用自定义字体修改qlabel字体、大小以及颜色
1.修改字体 引用Qt笔记(五十九)之Qt使用自定义字体_我是黄同学的博客-CSDN博客_qt 自定义字体 查阅资料发现这段修改字体代码 int font_Id = QFontDatabase::ad ...
- Qt5.12 QML——TextMetrics字体长度的测量指标
序言 用QML做一个按钮时,有需求是要求只有底下一横,但是不能靠太近,而且长度要刚刚好和字的长度一致,正当我查也查不出来时,被某群的群友启发,知道有一个TextMetrics可以提供相应字体的长度,但 ...
- Qt5.9学习笔记2-输入/显示/按钮/菜单/时间/字体/图片
一般属性在类的接口中有读取函数和设置函数,对于设置属性函数就是属性名前加set 如QSpinBox类中有属性value用来显示组件当前值,可以使用setValue()方法来设置该组件的值. 1.输入组 ...
- Qt5.9.1 简单字体设计(UI设计)
最近自学了下Qt,本节讲一下如何进行些简单的字体设计,有什么问题互相交流. 步骤如下: 一:创建一个Widget Application项目samp1,在创建窗体时选择基类QDialog,生成的类命名 ...
最新文章
- Linux环境编译安装Mysql以及补装innodb引擎方法
- ZeroMQ接口函数之 :zmq_msg_init - 初始化一个空的ZMQ消息结构
- 文件监视器——Filemon
- InetAddressImpl#lookupAllHostAddr慢/挂起
- C++11新特性之泛型编程与模板
- 【车联网】车联网产业发展报告(2019)
- ue4相机_UE4.24源码分析 - PlayerStart
- android nfc开发_意法半导体NFC产品线完整 满足多元应用_企业动态_新闻中心
- document.body
- Python 3.5 协程究竟是个啥
- 火山安卓文件名类操作
- 淘宝APP购物车测试用例
- c语言程序设计总结与体会,c语言程序设计个人总结
- 1232_使用SCons实现WindRiver Diab编译器的命令行自动化编译环境
- 从零到百亿互联网金融架构发展史
- ORACLE通过dblink同步SDO_ORDINATE_ARRAY_STR的数据
- 我要你觉得,我不要我觉得--根据企业现状实施DevOps
- K480N解决安装win10键盘失灵的方法
- 初识、初使 MySQL
- 北京工作居住证办理流程
热门文章
- 《Oracle PL/SQL程序设计(第5版)》一一2.4 执行必要的PL/SQL任务
- OSChina 周三乱弹 —— 谈什么对象?睡什么觉?
- scp_linux之间互传文件
- python3 Json转xmind代码与打开
- AI算法+EasyCVR打造智慧城市,构建万物互联智能世界
- android 控制POS机图文打印(一)
- 区块链最好的编程语言是什么?
- win11系统下安装lighttools8.6无加密狗版的方法
- CSS入门五:文本样式;字体颜色:英文字母,十六进制,RGB;文本颜色,字间距,行间距,对齐方式;下划线、上划线…,文本阴影,字母大小写,首行缩进
- Qt 获取 MacBook 设备序列号