qt - 如何初始化 QML 单例?
问题描述
我在https://github.com/jh3010-qt-questions/font_test有一个简单的测试项目,它演示了这个问题。
我有一个标签定义为:
Label // #1
{
text: "Pack my box with five dozen liquor jugs -- DEFAULT"
}
应该使用 qtquickcontrols2.conf 中定义的默认字体(Art Brewery)显示,但事实并非如此。
但是,如果我添加标签:
Label // #2
{
font.family: Fonts.robotoBold.name
text: "Pack my box with five dozen liquor jugs -- Roboto Bold"
}
然后,将使用 Art Brewery 字体绘制标签 #1。
正在发生的事情是,除非至少有一个对它的引用,否则 Fonts 单例不会被初始化。
我的问题是:如何初始化单例?
我试过这样的事情:
qmlRegisterSingletonType( QUrl( "file:///Users/jamesh/depot_qt/questions/font_test/assets/Fonts/Fonts.qml"), "Font", 1, 0, "Font" );
在我的 main.cpp 中,但它不起作用。
我的目录结构如下:
$ tree font_test
font_test
├── README.md
├── assets
│ └── Fonts
│ ├── Art\ Brewery.ttf
│ ├── Fonts.qml
│ ├── Roboto-Bold.ttf
│ ├── Roboto-BoldItalic.ttf
│ ├── Roboto-Light.ttf
│ ├── Roboto-LightItalic.ttf
│ ├── Roboto-Medium.ttf
│ ├── Roboto-MediumItalic.ttf
│ ├── Roboto-Regular.ttf
│ ├── Roboto-RegularItalic.ttf
│ ├── RobotoMono-Bold.ttf
│ ├── RobotoMono-BoldItalic.ttf
│ ├── RobotoMono-Light.ttf
│ ├── RobotoMono-LightItalic.ttf
│ ├── RobotoMono-Medium.ttf
│ ├── RobotoMono-MediumItalic.ttf
│ ├── RobotoMono-Regular.ttf
│ ├── RobotoMono-RegularItalic.ttf
│ └── qmldir
├── font_test.pro
├── font_test.pro.user
├── main.cpp
├── main.qml
├── qml.qrc
└── qtquickcontrols2.conf
[Controls]
Style=Material
[Material]
Primary=White
Foreground=#444444
Accent=Blue
Theme=Light
Font\Family=Art Brewery
[Universal]
Theme=System
我的main.cpp是:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.addImportPath( ":/" );
// qmlRegisterSingletonType( QUrl( "file:///Users/jamesh/depot_qt/questions/font_test/assets/Fonts/Fonts.qml"), "Font", 1, 0, "Font" );
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect( &engine,
&QQmlApplicationEngine::objectCreated,
&app,
[url](QObject *obj, const QUrl &objUrl )
{
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
},
Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
我的qml.qrc文件是:
<RCC>
<qresource prefix="/">
<file>main.qml</file>
<file>qtquickcontrols2.conf</file>
</qresource>
<qresource prefix="/Fonts">
<file alias="qmldir">assets/Fonts/qmldir</file>
<file alias="Fonts.qml">assets/Fonts/Fonts.qml</file>
<file alias="Art Brewery.ttf">assets/Fonts/Art Brewery.ttf</file>
<file alias="Roboto-Bold.ttf">assets/Fonts/Roboto-Bold.ttf</file>
<file alias="Roboto-BoldItalic.ttf">assets/Fonts/Roboto-BoldItalic.ttf</file>
<file alias="Roboto-Light.ttf">assets/Fonts/Roboto-Light.ttf</file>
<file alias="Roboto-LightItalic.ttf">assets/Fonts/Roboto-LightItalic.ttf</file>
<file alias="Roboto-Medium.ttf">assets/Fonts/Roboto-Medium.ttf</file>
<file alias="Roboto-MediumItalic.ttf">assets/Fonts/Roboto-MediumItalic.ttf</file>
<file alias="Roboto-Regular.ttf">assets/Fonts/Roboto-Regular.ttf</file>
<file alias="Roboto-RegularItalic.ttf">assets/Fonts/Roboto-RegularItalic.ttf</file>
<file alias="RobotoMono-Bold.ttf">assets/Fonts/RobotoMono-Bold.ttf</file>
<file alias="RobotoMono-BoldItalic.ttf">assets/Fonts/RobotoMono-BoldItalic.ttf</file>
<file alias="RobotoMono-Light.ttf">assets/Fonts/RobotoMono-Light.ttf</file>
<file alias="RobotoMono-LightItalic.ttf">assets/Fonts/RobotoMono-LightItalic.ttf</file>
<file alias="RobotoMono-Medium.ttf">assets/Fonts/RobotoMono-Medium.ttf</file>
<file alias="RobotoMono-MediumItalic.ttf">assets/Fonts/RobotoMono-MediumItalic.ttf</file>
<file alias="RobotoMono-Regular.ttf">assets/Fonts/RobotoMono-Regular.ttf</file>
<file alias="RobotoMono-RegularItalic.ttf">assets/Fonts/RobotoMono-RegularItalic.ttf</file>
</qresource>
</RCC>
我的项目文件是:
QT += quick
CONFIG += c++11
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp
RESOURCES += qml.qrc
# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH = $$PWD/assets
# Additional import path used to resolve QML modules just for Qt Quick Designer
QML_DESIGNER_IMPORT_PATH =
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
DISTFILES +=
我的Fonts.qml文件是:
pragma Singleton
import QtQuick 2.12
Item
{
readonly property FontLoader robotoBold: FontLoader { source: "qrc:/Fonts/Roboto-Bold.ttf" }
readonly property FontLoader robotoBoldItalic: FontLoader { source: "qrc:/Fonts/Roboto-BoldItalic.ttf" }
readonly property FontLoader robotoLight: FontLoader { source: "qrc:/Fonts/Roboto-Light.ttf" }
readonly property FontLoader robotoLightItalic: FontLoader { source: "qrc:/Fonts/Roboto-LightItalic.ttf" }
readonly property FontLoader robotoMedium: FontLoader { source: "qrc:/Fonts/Roboto-Medium.ttf" }
readonly property FontLoader robotoMediumItalic: FontLoader { source: "qrc:/Fonts/Roboto-MediumItalic.ttf" }
readonly property FontLoader robotoRegular: FontLoader { source: "qrc:/Fonts/Roboto-Regular.ttf" }
readonly property FontLoader robotoRegularItalic: FontLoader { source: "qrc:/Fonts/Roboto-RegularItalic.ttf" }
readonly property FontLoader robotoMonoBold: FontLoader { source: "qrc:/Fonts/RobotoMono-Bold.ttf" }
readonly property FontLoader robotoMonoBoldItalic: FontLoader { source: "qrc:/Fonts/RobotoMono-BoldItalic.ttf" }
readonly property FontLoader robotoMonoLight: FontLoader { source: "qrc:/Fonts/RobotoMono-Light.ttf" }
readonly property FontLoader robotoMonoLightItalic: FontLoader { source: "qrc:/Fonts/RobotoMono-LightItalic.ttf" }
readonly property FontLoader robotoMonoMedium: FontLoader { source: "qrc:/Fonts/RobotoMono-Medium.ttf" }
readonly property FontLoader robotoMonoMediumItalic: FontLoader { source: "qrc:/Fonts/RobotoMono-MediumItalic.ttf" }
readonly property FontLoader robotoMonoRegular: FontLoader { source: "qrc:/Fonts/RobotoMono-Regular.ttf" }
readonly property FontLoader robotoMonoRegularItalic: FontLoader { source: "qrc:/Fonts/RobotoMono-RegularItalic.ttf" }
readonly property FontLoader artBrewery: FontLoader { source: "qrc:/Fonts/Art Brewery.ttf" }
}
我在 assets/fonts 文件夹中的 qmldir 是:
singleton Fonts 1.0 Fonts.qml
我的main.qml是
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
import Fonts 1.0
//import "qrc:/Fonts/"
ApplicationWindow {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
Column
{
spacing: 8
anchors.fill: parent
anchors.margins: 20
Label // #1
{
text: "Pack my box with five dozen liquor jugs -- DEFAULT"
}
// Label // #2
// {
// font.family: Fonts.robotoBold.name
// text: "Pack my box with five dozen liquor jugs -- Roboto Bold"
// }
// Label // #3
// {
// font.family: Fonts.robotoMonoRegular.name // Fonts.robotoRegular.name
// text: "Pack my box with five dozen liquor jugs -- Roboto Mono"
// }
// Label // #4
// {
// text: "Pack my box with five dozen liquor jugs -- Art Brewery"
// font.family: Fonts.artBrewery.name
// font.pixelSize: 36
// }
}
}
解决方案
我确信有一个更好的解决方案,但有一个方法是找到一种方法来引用单例,以便加载所有内容。
我将 main.qml 修改为:
...
...
...
title: qsTr("Hello World")
property var fontReference: Fonts.objectName
Column
...
...
...
我不关心 fontReference 属性。我只需要一些方法来初始化字体。我假设在 main.cpp 中创建引擎实例后可以调用 C++ 方法,这将完成同样的事情,并且可能被认为是这种情况下的最佳实践。
推荐阅读
- javascript - 使用 JavaScript 添加/删除表行
- html - 垂直线性渐变
- sql - oracle错误信息输入值不够长
- python - 没有任何包的 Python 规范化
- swift - 使用 UIScrollView 滚动 TableView 和 Main Stack
- firebase - 是否可以创建离线 Firebase 应用程序?
- java - Scala 的偏函数有 Java 等价物吗?
- pip - 找不到满足通过 pip 安装 tensorflow 要求的版本
- javascript - 获取变量中的字符串以在 Javascript 中创建动态链接
- javascript - 在此处地图上隐藏/显示地图标记