Strange behavior with QQmlFileSelector
-
Hi folks!
I'm currently facing some strange behavior with the QQmlFileSelector from Qt 5.12.8.
First of all I want to introduce you to my filesystem structure:
/Base/Assets/+foo/error.png
/Base/Assets/+foo/+bar/logo.png
/Base/Assets/+foo/+bar/error.png
/Base/Assets/+foo/+car/[other pictures]
/Base/Interface/something.qml
/Base/Interface/something.ui.qml
/Base/Interface/else.qml
/Base/Interface/else.ui.qml
/Base/Interface/+bar/[other qml files]
/Base/Interface/+car/[other qml files]
/Base/Interface/+foo/something.qml
/Base/Interface/+foo/something.ui.qml
/Base/Interface/+foo/else.ui.qml
/Base/Interface/+foo/+bar/something.qml
/Base/Interface/+foo/+bar/something.ui.qml
/Base/Interface/+foo/+bar/else.ui.qml
/Base/Interface/+foo/+car/something.qml
/Base/Interface/+foo/+car/something.ui.qml
/Base/Interface/+foo/+car/else.ui.qmlThe resource file's base path qrc:/ points to /Base.
Applying the file selectors ["+foo"], ["+foo", "+bar"] or ["+foo", "+car"] is working properly for all the qml files.
Problems come up when I try to access a file selected picture from within a file selected qml file.
For example:
I do apply the file selectors ["+foo", "+bar"] and try to access the picture /Base/Assets/+foo/+bar/logo.png from /Base/Interface/+foo/+bar/else.ui.qml, I can do that by saying:
Image { source: "qrc:/Assets/logo.png"
By injecting with gammaray, I can see that the images source is resolved to:
qrc:/Assets/+foo/+bar/logo.pngInterestingly I get a completely different result when I do that by saying:
Image { source: "qrc:/Assets" + "/logo.png"
With that, the images source is resolved to:
qrc:/Assets/logo.pngNow I want to do same for /Base/Assets/+foo/+bar/error.png from /Base/Interface/+foo/+bar/something.qml:
StateChangeScript { script: imageSource = "qrc:/Assets/error.png" }
where 'imageSource' is a string which is bound to an images source under certain circumstances.
This is not working, since the images source gets resolved to qrc:/Assets/error.pngNext I tried to do this for the file selector ["+foo"] and /Base/Assets/+foo/error.png from /Base/Interface/+foo/something.qml:
PropertyChanges { target: image source: "qrc:/Assets/error.png" }
This is also not working, since the images source gets resolved to qrc:/Assets/error.png as well.
So I decided to give it a try and used relative paths:
"../../../Assets/logo.png" @ /Base/Interface/+foo/+bar/else.ui.qml gets resolved correctly (to qrc:/Assets/+foo/+bar/logo.png).
"../../../Assets/error..png" @ /Base/Interface/+foo/+bar/something.qml gets resolved correctly (to qrc:/Assets/+foo/+bar/error.png).
"../../Assets/error..png" @ /Base/Interface/+foo/something.qml gets resolved correctly (to qrc:/Assets/+foo/error.png).So far so good.
But to make the confusion complete here is the output from Qt.resolvedUrl for some relative paths:
@/Base/Interface/+foo/+bar/something.qml with file selectors ["+foo", "+bar"]:
+++ Qt.resolvedUrl("./"): qrc:/Interface/+foo/+bar/
+++ Qt.resolvedUrl("../"): qrc:/Interface/+foo/+bar/
+++ Qt.resolvedUrl("../../"): qrc:/
+++ Qt.resolvedUrl("../../../"): qrc:/
where "../Assets/error.png" gets resolved to "qrc:/Interface/Assets/error.png"@/Base/Interface/+foo/+car/something.qml with file selectors ["+foo", "+car"]:
+++ Qt.resolvedUrl("./"): qrc:/Interface/+foo/+car/
+++ Qt.resolvedUrl("../"): qrc:/
+++ Qt.resolvedUrl("../../"): qrc:/
+++ Qt.resolvedUrl("../../../"): qrc:/
where "../Assets/error.png" gets resolved to "qrc:/Assets/+foo/error.png" (which is correct)@/Base/Interface/+foo/something.qml with file selector ["+foo"]:
+++ Qt.resolvedUrl("./"): qrc:/Interface/+foo/
+++ Qt.resolvedUrl("../"): qrc:/
+++ Qt.resolvedUrl("../../"): qrc:/Does anyone have an explanation for that, or at least an idea what can cause such behavior?
-
Hello again!
I stumbled into this behavior again, as one of my files, where I used relative paths, has changed its Qt.resolvedUrl behavior "overnight".
I was not yet able to find out which commit has broken it, as the the built binaries do no behave the same all times, weird... :O
The file lies under @/Base/Interface/+foo/ and Qt.resolvedUrl("../") does now resolve to qrc:/Interface/+foo/ and not qrc:/ as like before.
The need for using relative paths came as the absolute paths with "qrc:/" were not working as expected under all circumstances (see previous post).
So I decided to give that a closer look again.
Here is what I found out so far:
All that cases I had shown in the first part of the previous post, do work correctly when I encapsulate the source's string into a Qt.resolvedUrl.
That means, I no longer get a completely different result for
Image { source: "qrc:/Assets" + "/logo.png"
when I do that by saying:
Image { source: Qt.resolvedUrl("qrc:/Assets" + "/logo.png")
With that the image's source gets resolved correctly to qrc:/Assets/+foo/+bar/logo.png
The same counts for
StateChangeScript { script: imageSource = Qt.resolvedUrl("qrc:/Assets/error.png") }
where 'imageSource' is still a property of type string, but the image's source gets resolved correctly to qrc:/Assets/+foo/+bar/error.png.
And also for
PropertyChanges { target: image source: Qt.resolvedUrl("qrc:/Assets/error.png") }
the source gets resolved correctly to qrc:/Assets/+foo/error.png
Does anyone have a clue on what Qt.resolvedUrl does in an other way than the implicit conversion of strings to urls?
Naively you will think like, this will happen internally by using Qt.resolvedUrl, but yeah...Regards, matzze.