Import of remote directory with qml files does not work
-
I have a QtQuick application, which must load remote qml files. In order to do this I found in the docs that an import can be a remote directory. But while this kind of works with local directories, it doesnt work with remote directories on a webserver. What am I doing wrong?
Here are some examples to explain what I want, what works and what doesnt work (on mint linux, 64bit):
Example1:
- /home/user/temp/qml consists of the file Toaster.qml and a qmldir file with the line "Toaster Toaster.qml"
- Toaster.qml contains only a simple rectangle
- The main.qml looks like this:
@import QtQuick 2.2
import "../../../../../../../../temp/qml"Rectangle {
width: 360
height: 360Toaster { }
}@
This works fine, the QT Creator recognizes the new type "Toaster" and the application starts without errors.
Example2:
Same Setup as above, but instead of using a relative path in the import I use the absolute path to the external dir:
"import "/home/user/temp/qml""This time QT Creator still recognizes the type "Toaster", but when starting the application, I get an error:
'import "/home/user/temp/qml" has no qmldir and no namespace'
Of course, the qmldir is still in the directory, since it is the same setup as described in example1Alternating the import to "'import "/home/user/temp/qml" as Remote" and use Remote as local namespace for the "Toaster" also doesnt fix it, it just leads to another errormessage:
"Type Remote.Toaster unavailable
Remote.Toaster {
^
/home/user/temp/qml/Toaster.qml: Network errorExample 2 is not the way I want it to work (since it is still a local dir), but maybe it can help to solve the problem with example3
Example3:
- I have a locally running Java Jetty WebServer (to simulate a remote source) with a static resource, which can be listed (ResourceHandler.setDirectoriesListed(true) for those who know jetty) and contains the files as described in example1 in a folder named "content"
Now I try to import the remote dir with the following import:
"import "http://192.168.178.33/content""But QT Creator underlines the import with the error "file or directory not found", so that the type "Toaster" is not available.
So what am I doing wrong here? Is there something that has to be configured in the project file in order to make remote directories work? Or is my approach with a webserver and a listed dir wrong (so whats the right way then?)?
I really appreciate any help, because that would solve a huge problem for me :)
-
Update:
Tried it with nginx instead of jetty and still there is the error “file or directory not found” at the import. But if I run the file with the usage of "Toaster" it is loaded from the url, which is great.But now I have the next error:
The qml which uses the remote import, is loaded with "Qt.createQmlObject". If I now load this qml with the createQmlObject method, I get the error:
"Error: Qt.createQmlObject(): Component is not ready"I can fix this, with a for loop, because after some tries the error is gone. But there must be a better solution for this problem.
@ for (i; i<15; i++){
try {
container.dynamicObject = Qt.createQmlObject(content, container);
break;
}
catch (err) {} }@
-
Hi,
Your first import is a relative path import. When importing a local directory via relative import, the qmldir in the directory is treated as a directory listing file.
Your second import is an absolute path import. Absolute path imports are treated as module imports unless you explicitly provide a qualified namespace (because directory listing qmldir files do not define a type namespace). Hence, the warning about no qmldir is because the qmldir in that path is not a module definition file (it's a directory listing file) and you do not import the directory into a qualified namespace (using the 'as' syntax).
Your third import should work, but you can ignore QtCreator's "file or directory not found" error (because QtCreator will not access the remote URL and parse the qmldir file, so it doesn't know which types are available or not).
The error you get from Qt.createQmlObject() is because it has to load the content asynchronously via a socket. Don't use Qt.createQmlObject() for this - instead, use Qt.createComponent() and then wait until the component's status is Ready before you attempt to call the createObject() function provided by the component.
Cheers,
Chris. -
Thanks again for a detailed answer which clears many things up.
Unfortunately I cant use Qt.createComponent(), because the qml file that is dynamically loaded is generated at runtime on the remote repository, so that I dont have a physical file available :/