简体   繁体   中英

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

Is there any way how to implement dynamical file-resolver for missing Qml components in QmlEngine? How to implement dynamically loading of external resources to QmlEngine?

I can use following snippet to load qml component from any data stream:

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

but when passed component refers to another one (not already loaded), QmlEngine stopped because of missing resource.

Is there any event/callback where it is possible to handle such missing resource?

Added use-case scenario:

We're developing some QML visual components. Some components are implemented as .qml files and some as QQuickItem .

For example imagine following situation (it's very simplified):

  • QmlItem "DiagramPoint", implemented in point.qml
  • QmlItem "Line" implemented in line.qml, class is using "DiagramPoint" item
  • QQuickItem (c++) "ConnectedLine" which internally using "Line" object
  • QmlProject which using "ConnectedLine" components.

In case that point.qml and line.qml are located on hdd or stored inside Qt Resources, everything works automatically. But what we would like to achieve is to store these files in encrypted form in our internal .dat file and decode it only on demand.

We're able to decode and load "Line" object from "ConnectedLine" implementation. But in case that "Line" (line.qml) depends on another encrypted file "DiagramPoint" (point.qml), this solution doesn't work.

Another possible solution

Another solution could be to register all decrypted .qml files on application startup and than use it. Something simillar to qmlRegisterType which allows to register c++ QQuickItems to QmlEngine .

Unfortunately none of these methods allow to register Qml snippet from string buffer.

I'm still a bit unsure about how you would do this, but you might find QQmlAbstractUrlInterceptor useful:

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.

It says that its synchronous, so perhaps you could decode the QML files when the URLs are intercepted to ensure that they exist?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM