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 the qrc:/.... on the other hand, a file: 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...

  • Hi! If I do the following with Qt 5.7 on Windows...

    import "file:one/code.js" as MyOne


    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 containing Stuff.
    • Adding a Stuff/qmldir containing the usual declarations of the .js files I want to expose. (I also added a module 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 and SomeOtherJsStuff but that's fine for what I have.

Log in to reply

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.