如何在一个类中拥有多个FontLoader对象?

时间:2016-05-07 00:55:44

标签: qt qml

我正在编写一个客户端已提供自定义字体的应用程序。该字体有四个独立的otf个文件,一个用于常规,粗体,斜体和粗体斜体。如果我想在我的班级中只使用这四种字体中的一种,我就像这样创建FontLoader

FontLoader { id: clientFontRegular; source: "qrc:/client/fonts/Font-Regular.otf" }

然后我可以将它用于我的页面上的任何控件,如下所示:

font.family: clientFontRegular.name

我的问题是我的页面上有多个控件,我想使用常规的一些,一些粗体,一些其他的斜体等。为此,我添加了FontLoader个对象其他字体也是如此:

FontLoader { id: clientFontBold; source: "qrc:/client/fonts/Font-Bold.otf" }
FontLoader { id: clientFontItalic; source: "qrc:/client/fonts/Font-Italic.otf" }
FontLoader { id: clientFontBoldItalic; source: "qrc:/client/fonts/Font-BoldItalic.otf" }

但这不能正常工作。所有四个ID(clientFontRegular,clientFontBold,clientFontItalic和clientFontBoldItalic)都可以在页面的任何位置使用(即不会崩溃或最终使用系统字体),但无论粗体字体是什么,都使用字体。

我知道我的所有四个otf文件都是有效的,因为如果我注释掉除一个文件的FontLoader以外的所有文件并且仅使用那个文件,则会正确呈现自定义字体。试图在一个类中定义多个FontLoader似乎有一个问题(我在网上看到的FontLoader样本都没有使用多个自定义字体)。

有人知道怎么做吗?

2 个答案:

答案 0 :(得分:6)

我也在努力解决同样的问题,并想知道为什么文档中没有任何关于它的内容。这就是我的工作方式:

首先,我定义了一个自定义Text元素(例如Label.qml),其中FontLoader元素用于每种字体样式,如下所示:

import QtQuick 2.5

Text {
    FontLoader  { id: loader; source: "fonts/Blogger_Sans.otf"; }
    FontLoader  { source: "fonts/Blogger_Sans-Italic.otf"; }
    FontLoader  { source: "fonts/Blogger_Sans-Light.otf"; }
    FontLoader  { source: "fonts/Blogger_Sans-Medium.otf"; }
    FontLoader  { source: "fonts/Blogger_Sans-Bold.otf"; }
    FontLoader  { source: "fonts/Blogger_Sans-Light_Italic.otf"; }
    FontLoader  { source: "fonts/Blogger_Sans-Medium_Italic.otf"; }
    FontLoader  { source: "fonts/Blogger_Sans-Bold_Italic.otf"; }

    font.family: loader.name;
}

"技巧"是不动态重新分配Text元素的font.family属性。这已足以控制字体样式:

Column {
    anchors.centerIn: parent;

    MyLib.Label {
        text: "Blogger_Sans"
    }

    MyLib.Label {
        text: "Blogger_Sans-Italic"
        font.italic: true;
    }

    MyLib.Label {
        text: "Blogger_Sans-Light"
        font.weight: Font.Light;
    }

    MyLib.Label {
        text: "Blogger_Sans-Medium"
        font.weight: Font.Medium;
    }

    MyLib.Label {
        text: "Blogger_Sans-Bold"
        font.weight: Font.Bold;
    }

    MyLib.Label {
        text: "Blogger_Sans-Light_Italic"
        font.weight: Font.Light;
        font.italic: true;
    }

    MyLib.Label {
        text: "Blogger_Sans-Medium_Italic"
        font.weight: Font.Medium;
        font.italic: true;
    }

    MyLib.Label {
        text: "Blogger_Sans-Bold_Italic"
        font.weight: Font.Bold;
        font.italic: true;
    }
}

我只是假设,但看起来一旦加载了字体(就像在这种情况下是匿名的FontLoader),它们会被记忆并在使用可用的字体属性指定它们时自动可用。但它只是在猜测。

修改

正如peppe的评论中指出的那样,也可以使用QFontDatabase::addApplicationFont直接在C ++中加载自定义字体:

QFontDatabase::addApplicationFont(resDir + "fonts/Blogger_Sans.otf");
QFontDatabase::addApplicationFont(resDir + "fonts/Blogger_Sans-Bold_Italic.otf");
QFontDatabase::addApplicationFont(resDir + "fonts/Blogger_Sans-Medium_Italic.otf");
QFontDatabase::addApplicationFont(resDir + "fonts/Blogger_Sans-Light_Italic.otf");
QFontDatabase::addApplicationFont(resDir + "fonts/Blogger_Sans-Italic.otf");
QFontDatabase::addApplicationFont(resDir + "fonts/Blogger_Sans-Bold.otf");
QFontDatabase::addApplicationFont(resDir + "fonts/Blogger_Sans-Medium.otf");
QFontDatabase::addApplicationFont(resDir + "fonts/Blogger_Sans-Light.otf");

现在QML中提供了字体和相关样式:

Text {
    font.family: "Blogger Sans" // note the use of the font family name
    text: "MyText"
    font.bold: true
    font.italic: true
}

C ++方法看起来更干净,并且允许您在不使用文件路径的情况下指定字体,这是另一个很大的优势。

答案 1 :(得分:1)

我只花了一个小时的大部分时间试错了这个。实际上,虽然qCring的回答有效,但它实际上要简单得多。与

FontLoader { id: clientFontBold; source: "qrc:/client/fonts/Font-Bold.otf" }
FontLoader { id: clientFontItalic; source: "qrc:/client/fonts/Font-Italic.otf" }
FontLoader { id: clientFontBoldItalic; source: "qrc:/client/fonts/Font-BoldItalic.otf" }

所有FontLoaders都以相同的默认名称结束,因此clientFontBold.name == clientFontItalic.name == clientFontBoldItalic.name显然Qt决定映射最后注册的字体。您可以通过更改顺序轻松查看此内容,以便clientFontItalic最后一次。然后,使用clientFontBold.name的所有文字都将为斜体。

解决方案当然是命名它们:

FontLoader { id: clientFontBold; name: "MyFontBold"; source: "qrc:/client/fonts/Font-Bold.otf" }
FontLoader { id: clientFontItalic; name: "MyFontItalic"; source: "qrc:/client/fonts/Font-Italic.otf" }
FontLoader { id: clientFontBoldItalic; name: "MyFontBoldItalic"; source: "qrc:/client/fonts/Font-BoldItalic.otf" }

现在clientFontBold.name != clientFontItalic.name != clientFontBoldItalic.name并加载正确的字体。我不知道为什么未命名的字体以相同的名字结尾的事实在示例中的任何地方都没有记录。