[SOLVED] Creating a QML Image that will load different source if one source fails to load
-
I am trying to create a QML Element that has three sources:
source1: This is the first source that will be attempted to be loaded
source2: If source1 is empty or it fails loading this source will be used
sourceError: If source1 and source2 fail to load this one will be used.I have tried doing this with states, but get errors like
<Unknown File>: QML StateGroup: Can't apply a state change as part of a state definition.I get that error when I change the state when the image status changes to Image.Error.
So I tried just updating the source property. I am seeing two issues:
- If i do the following the status remains Image.Null
@
souce = "/img/path/does/not/exist/img.png"
console.log("status " + (status == Image.Null)); // logs 'status true'
@
2. So I try setting the source on the "onStatusChanged" signal; if status == Image.Error change to the next source. This works with 2 source just fine, but when I add in the third source it only attempts to load the first two. I'm assuming it doesn't want to emit the onStatusChanged signal within an onStatusChanged signal.Has anyone tried to do this with success. Any hints would be great.
I believe I could get this to work If I could add property changes to the end of the event queue ("AWT calls is that, not sure what qt calls is")
- If i do the following the status remains Image.Null
-
When you say you've tried it using states, how did you try it?
-
Logic with states:
I had 3 states:
- "source1":
- changed the image source to source1 property
- "source2":
- changed the image source to source2 property
- "sourceError"
- changed the image source to sourceError property
on status changed to Image.Error I check the current state and changed it next in line. For example, if the current state was "source1" I would change it to "source2". This would give me the following error:
<Unknown File>: QML StateGroup: Can’t apply a state change as part of a state definition. -
I was able to get it to work using the following (though I'm sure there are a lot better ways):
@
import QtQuick 1.0Rectangle {
width: 360
height: 360Image {
id: img
property string source1: "!red.png"
property string source2: "!green.png"
property string source3: "blue.png"property int curr: 1 signal failedToLoad anchors.centerIn: parent source: source1 onStatusChanged: { console.log("Status changed to " + status); if (status == Image.Error) { console.log("source: " + source + ": failed to load"); source = ""; failedToLoad() } } onFailedToLoad: { curr++; } onCurrChanged: { if (curr == 1) { source = source1; } else if (curr == 2) { source = source2; } else if (curr == 3) { source = source3; } else { console.log("Cannot open"); } }
}
}
@Quick and dirty, but it seems to work.
-
I haven't tested it, but maybe something like this?
@
Image {
id: image
property int errorCount: 0
property string altSource
property string errorSourceonStatusChanged: { if (image.status == Image.Error) { errorCount += 1; if (errorCount == 1) image.source = image.altSource; else image.source = image.errorSource; } } }
@
-
[quote author="Bradley" date="1310511624"]I haven't tested it, but maybe something like this?
[/quote]
That seemed to suffer from the same problem that he mentioned before. I think what's happening is that for some reason, if the status == Image.Error, and you try to load another image with an error, the status never changes from Image.Error, thus never triggering the onStatusChanged again. A workaround solution seems to be to reset the image source to "" in between load attempts, thus changing the status to Image.Null in the interim.
I tweaked your code to the following:
@
Image {
id: image
property int errorCount: 0
property string altSource
property string errorSourceanchors.centerIn: parent onStatusChanged: { if (image.status == Image.Error) { errorCount += 1; if (errorCount == 1) { image.source = "" // Gotta clear the source image.source = image.altSource; } else { image.source = image.errorSource; } } }
}
@and it worked.
Edit to add: And much more cleanly than my original kludgy workaround. :)
-
That was the problem.
Thanks for you help