Qt- 从资源中添加自定义字体

24

我将这个字体添加到资源中:BYekan.ttf
我想在我的应用程序中使用这个字体。我已经尝试过:

    QFont font(":/images/font/BYekan.ttf");
    nLabel->setFont(font);
    nLabel->setText(tr("This is for test"));
    layout->addWidget(nLabel);

但是,我猜它没起作用。如何使用?

编辑: 阅读这个问题后,我又试了一遍:

int fontID(-1);
bool fontWarningShown(false);
QFile res(":/images/font/Yekan.ttf");
if (res.open(QIODevice::ReadOnly) == false) {
    if (fontWarningShown == false) {
        QMessageBox::warning(0, "Application", (QString)"Impossible d'ouvrir la police " + QChar(0x00AB) + " DejaVu Serif " + QChar(0x00BB) + ".");
        fontWarningShown = true;
    }
}else {
    fontID = QFontDatabase::addApplicationFontFromData(res.readAll());
    if (fontID == -1 && fontWarningShown == false) {
        QMessageBox::warning(0, "Application", (QString)"Impossible d'ouvrir la police " + QChar(0x00AB) + " DejaVu Serif " + QChar(0x00BB) + ".");
        fontWarningShown = true;

    }
    else
        nLabel->setFont(QFont(":/images/font/Yekan.ttf", 10));
}

我比较了这种字体和其他字体,但在Qt上并没有任何不同。为什么?


尝试使用以下代码: QFont font(":/images/font/BYekan.ttf"); nLabel->setFont(font); - Ankur
我尝试了,但仍然不起作用。 - Farzan Najipour
4个回答

57
int id = QFontDatabase::addApplicationFont(":/fonts/monospace.ttf");
QString family = QFontDatabase::applicationFontFamilies(id).at(0);
QFont monospace(family);

如何使用它? nLabel->setFont(monospace(family));错误:没有与“(QString&)”的调用匹配的内容。 - Farzan Najipour
2
nLabel->setFont(monospace); 不,像这样。 - Ankur
5
ID为-1,如果字体无法加载。 - Paglian
我注意到加载仅使用系统安装字体的应用程序比使用嵌入字体的应用程序要快得多。此外,我尝试在qrc文件之外使用未压缩的字体,但结果相同。 - S.M.Mousavi
1
在我的情况下,QFile::exists 返回 true,但是 QFontDatabase::addApplicationFont 返回 -1。这可能是什么原因? - Indiana Kernick
在我的情况下,文件名的大小写拼写不同,这就是为什么它返回-1的原因。 - Ambrus Tóth

5
在QML中,你可以实现以下功能:
FontLoader { id: font; source: "/fonts/font.otf" }

1
没有,你看,这些并不是我做的。对我来说,我所做的是创建一个 ~/.font/ 目录(如果它不存在),然后将 ttf 文件复制到这个目录中,Linux 就会识别它。但是,在我的情况下,我正在编写一个 QT 应用程序,这些字体有名称,那么 Linux 怎么知道这个名称呢?如果运行以下命令:
fc-list

它会输出整个系统的所有字体信息,你可以搜索你添加的字体。
输出结果大致如下:
...
/usr/share/texmf/fonts/opentype/public/lm/lmsans17-oblique.otf: Latin Modern Sans,LM Sans 17:style=17 Oblique,Italic
/home/XXX/.fonts/PAPYRUS.TTF: Papyrus:style=Regular,Normal,obyčejné,Standard,Κανονικά,Normaali,Normál,Normale,Standaard,Normalny,Обычный,Normálne,Navadno,Arrunta
/usr/share/fonts/X11/Type1/n019064l.pfb: Nimbus Sans L:style=Bold Condensed Italic
...

每行冒号后输出的部分是该用户在Linux内部看到的字体名称。因此,这些是“Latin Modern Sans,LM Sans 17”/“Papyrus”/“Nimbus Sans L”。因此,Linux看到它们,您作为用户运行的所有应用程序也会看到它们(例如Gimp、窗口管理器、QT应用程序等等)。
在您的QT应用程序中,您调用您感兴趣的字体,例如我对Papyrus字体感兴趣:
tabWidget->setFont( QFont( "Papyrus",10 ) );

然后,QT应用程序确实选择了该字体...如果您想使字体系统范围内可用,则需要找到字体目录的位置,从我所看到的内容来看,它是/usr/share/fonts/truetype/,您需要在其中创建一个子目录以存放字体,但其他发行版可能位于不同位置,您可能需要再次确认。无论如何,您可以将ttf文件放在那里。如果这样做,您可能需要考虑运行fc-cache -fv,因为它将遍历TrueType子目录,寻找新添加的字体。在Linux下涉及任何字体的问题时,请运行fc-list。它可以解决各种混乱和误解,并为Linux字体的黑暗和神秘世界带来光明。

如果我将字体复制(或链接)到一个被识别的目录中,那么使用addApplicationFont的解决方案就不是必需的。在我的情况下,字体没有在/usr/share/fonts中找到,而是在/usr/lib/fonts中找到的。 - Ernie Mur

1
我遇到了与原问题中报告的相同的问题。然而,上述提供的解决方案(答案以“int id = QFontDatabase :: addApplicationFont ...”开头)并没有起作用,正如上面的评论中所看到的那样。addApplicationFont返回-1。
原因是,在调用函数addApplicationFont的字符串中有一个前导“:”。我将其删除。现在它对我有效(在Linux上使用Qt 5.5.1和Qt 4.8.6进行测试),并返回0。在Windows上,可能需要在前面添加驱动器号。
注意:我必须提供字体文件的完整路径(例如/usr/share/fonts/ttf/droid/DroidSansFallbackFull.ttf)。

我可以看出你提供了一些有趣的额外见解(尽管这超出了我的专业能力范围)。然而,你的措辞很容易被误解为“我也是”或者是你的问题。这可能会(错误地和不应该)给你带来某种麻烦。我建议重新措辞并强调你解释如何解决评论中观察到的问题的部分。也许可以以“我想为上面评论中描述的问题添加一个解决方案。”开头。我认为这样可以让你被认为是一个认真的贡献者。 - Yunnosch
干得好。然而,“答案1”是含糊不清的,请注意用户可以按年龄、投票和活动排序答案。因此,没有明确的编号。使用回答者的姓名和可能的简短摘要。即使是“最老的”(如果你是这个意思),也不可靠,因为答案可以被删除和恢复。 - Yunnosch
请理解我无法点赞,因为我对实际技术问题一无所知。 - Yunnosch
1
请仔细阅读问题...他想从Qt资源系统中加载字体..该系统通过前缀":/"提供对文件的访问..你所说的是不正确的:原因是有一个前导符号“:”。 - Mohammad Kanan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接