Importing QML/js non-resource files from QML in a resource... expected behaviour?
-
I have an application with most of its QML in resources.
For various reasons, there's also some QML and javascript files which lives out in "regular" files, but needs to be imported by the resources QML.
I import these with some imports like
import "file:Stuff/somejsstuff.js" as SomeJsStuff
and find that works on Linux and OSX (the application takes the trouble to locate the directory containing Stuff and change working directory to there; on OSX and iOS the files are in the application bundle).
However on iOS, when a resource-domain QML file in
qrc:/MyResources/
tries to do such an import, I get messages like:qrc:/MyResources/Stuff/somejsstuff.js: File not found.
which kind of makes sense when you think about it:
file:Stuff/somejsstuff.js
isn't an absolute path so it sort of makes sense for it to try and combine it with the path to the current QML file's path in theqrc:/
.... on the other hand, afile:
prefix ought to make it pretty clear the target isn't intended to be found in the resource hierarchy, and the other platforms tried do seem to take the file path to be relative to the CWD instead.This begs the questions:
-
Which of these behaviours is "correct" or "intended"? iOS'? Or what I'm seeing on Linux & iOS? (Worth raising a Jira issue?)
-
What's a workround to achieve what I'm trying to do on iOS? Providing an absolute path to 'Stuff' is slightly complicated because of iOS' sandboxing. My app does make the application path available as a context property and I did try
import stuffUrl+"/Stuff/somejsstuff.js" as SomeJsStuff
but import obviously isn't expecting to deal with javascript expressions for its arguments.
Actually, I've just noticed
QQmlEngine::importPathList()
so I'm going to see if that can help... -
-
OK I solved this by:
- Having my app's setup do
engine()->addImportPath(...);
to the directory containingStuff
. - Adding a
Stuff/qmldir
containing the usual declarations of the .js files I want to expose. (I also added amodule Stuff
line; not sure it's actually necessary). - Changing my qrc-domain QML files' imports to simply
import Stuff 1.0
.
It's slightly non-equivalent to what I had before in that previously one qrc-domain QML file might have contained
import "file:Stuff/somejsstuff.js" as SomeJsStuff
and another one might have contained
import "file:Stuff/someotherjsstuff.js" as SomeOtherJsStuff
whereas now they just all do
import Stuff
and have visibility of both
SomeJsStuff
andSomeOtherJsStuff
but that's fine for what I have. - Having my app's setup do
-
Hi! If I do the following with Qt 5.7 on Windows...
import "file:one/code.js" as MyOne
or
import "file:../two/code.js" as MyTwo
I get runtime error:
ASSERT: "!url.isRelative() && (QQmlFile::urlToLocalFileOrQrc(url).isEmpty() || !QDir::isRelativePath(QQmlFile::urlToLocalFileOrQrc(url)))" in file qml\qqmltypeloader.cpp, line 1677
-
Hi! If I do the following with Qt 5.7 on Windows...
import "file:one/code.js" as MyOne
or
import "file:../two/code.js" as MyTwo
I get runtime error:
ASSERT: "!url.isRelative() && (QQmlFile::urlToLocalFileOrQrc(url).isEmpty() || !QDir::isRelativePath(QQmlFile::urlToLocalFileOrQrc(url)))" in file qml\qqmltypeloader.cpp, line 1677
@Wieland Thanks for the interesting data-point. I just checked in some debug builds here and I don't see that (at least I don't see it on Linux... on OSX doing macdeployqt with -use-debug-libs doesn't get me an executable which will start up). On both systems I'm just using Qt as downloaded by the MaintainanceTool... I've no idea what any debug libs it comes with have been compiled with though ... asserts on or off?)
Anyway that assert message looks like a pretty big hint URLs for imports need to be absolute. I did find a workround... will put it in next post.
-
OK I solved this by:
- Having my app's setup do
engine()->addImportPath(...);
to the directory containingStuff
. - Adding a
Stuff/qmldir
containing the usual declarations of the .js files I want to expose. (I also added amodule Stuff
line; not sure it's actually necessary). - Changing my qrc-domain QML files' imports to simply
import Stuff 1.0
.
It's slightly non-equivalent to what I had before in that previously one qrc-domain QML file might have contained
import "file:Stuff/somejsstuff.js" as SomeJsStuff
and another one might have contained
import "file:Stuff/someotherjsstuff.js" as SomeOtherJsStuff
whereas now they just all do
import Stuff
and have visibility of both
SomeJsStuff
andSomeOtherJsStuff
but that's fine for what I have. - Having my app's setup do