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

时间:2016-01-06 16:52:37

标签: qt qml qtquick2

有没有办法如何在QmlEngine中为缺少的Qml组件实现动态文件解析器?如何实现动态加载外部资源到QmlEngine?

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

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

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

是否有可以处理此类缺失资源的事件/回调?

添加了用例场景:

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

例如,想象以下情况(它非常简化):

  • QmlItem" DiagramPoint",在point.qml
  • 中实现
  • QmlItem" Line"在line.qml中实现,类正在使用" DiagramPoint"项目
  • QQuickItem (c++)" ConnectedLine"内部使用" Line"对象
  • QmlProject使用" ConnectedLine"组件。

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

我们能够解码并加载" Line"对象来自" ConnectedLine"实现。但是如果" Line" (line.qml)取决于另一个加密文件" DiagramPoint" (point.qml),这个解决方案不起作用。

另一种可能的解决方案

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

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

1 个答案:

答案 0 :(得分:1)

我仍然不确定你会如何做到这一点,但你可能会发现QQmlAbstractUrlInterceptor有用:

  

QQmlAbstractUrlInterceptor 是一个接口,可用于在QML引擎使用之前更改URL。此主要用于将文件URL更改为其他文件URL,例如为当前平台选择不同的图形资源。

     

根据当前QML上下文的文件路径解析相对URL。在为加载的QML文件设置基本路径之后,也会发生URL拦截。这意味着为该QML文件加载的内容使用截获的URL,但在文件内部,预截取的URL用于解析相对路径。这允许拦截.qml文件加载,而不需要拦截内容中的所有路径(或本地类型)插入不同的相对路径。

     

与setNetworkAccessManagerFactory相比,QQmlAbstractUrlInterceptor会影响所有URL和路径,包括本地文件和嵌入式资源文件。 QQmlAbstractUrlInterceptor是同步的,对于异步文件,必须返回带有异步方案的url(例如http或由您自己的自定义QNetworkAccessManager处理的自定义方案)。您可以使用QQmlAbstractUrlInterceptor将文件URL更改为联网由您自己的自定义QNetworkAccessManager处理的URL。

     

要实现对自定义网络方案的支持,请参阅setNetworkAccessManagerFactory。

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