如何为 Qt 5.5 + QtQuick 2.5 定义 Qml 组件文件解析器?

How to define Qml component file resolver for Qt 5.5 + QtQuick 2.5?

有什么方法可以实现动态文件解析器来解决 QmlEngine 中缺少的 Qml 组件吗? QmlEngine如何实现动态加载外部资源?

我可以使用以下代码片段从任何数据流加载 qml 组件:

QUrl uri(...)
QByteArray data(...);
QQmlComponent::setData(data,uri);

但是当传递的组件引用另一个组件(尚未加载)时,QmlEngine 因缺少资源而停止。

有没有event/callback可以处理这种缺失资源的地方?

添加的用例场景:

我们正在开发一些 QML 可视化组件。一些组件实现为 .qml files,一些组件实现为 QQuickItem

例如想象以下情况(非常简单):

如果 point.qml 和 line.qml 位于硬盘上或存储在 Qt 资源中,一切都会自动运行。但我们想要实现的是将这些文件以加密形式存储在我们的内部 .dat file 中,并仅在需要时对其进行解码。

我们能够从 "ConnectedLine" 实现中解码和加载 "Line" 对象。但是如果"Line"(line.qml)依赖于另一个加密文件"DiagramPoint"(point.qml),这个解决方案就不起作用了。

另一种可能的解决方案

另一个解决方案可能是在应用程序启动时注册所有解密的 .qml 文件,然后使用它。类似于 qmlRegisterType 的东西允许将 c++ QQuickItems 注册到 QmlEngine

不幸的是,none 这些方法允许从字符串缓冲区注册 Qml 片段。

我仍然不太确定您将如何执行此操作,但您可能会发现 QQmlAbstractUrlInterceptor 有用:

QQmlAbstractUrlInterceptor is an interface which can be used to alter URLs before they are used by the QML engine. This is primarily useful for altering file urls into other file urls, such as selecting different graphical assets for the current platform.

Relative URLs are intercepted after being resolved against the file path of the current QML context. URL interception also occurs after setting the base path for a loaded QML file. This means that the content loaded for that QML file uses the intercepted URL, but inside the file the pre-intercepted URL is used for resolving relative paths. This allows for interception of .qml file loading without needing all paths (or local types) inside intercepted content to insert a different relative path.

Compared to setNetworkAccessManagerFactory, QQmlAbstractUrlInterceptor affects all URLs and paths, including local files and embedded resource files. QQmlAbstractUrlInterceptor is synchronous, and for asynchronous files must return a url with an asynchronous scheme (such as http or a custom scheme handled by your own custom QNetworkAccessManager). You can use a QQmlAbstractUrlInterceptor to change file URLs into networked URLs which are handled by your own custom QNetworkAccessManager.

To implement support for a custom networked scheme, see setNetworkAccessManagerFactory.

它说它是同步的,所以也许您可以在拦截 URL 时解码 QML 文件以确保它们存在?