image-based off/on state component - best practice
-
What is the best practice for creating a component, with different images, for off and on states?
Like a toggle switch, with one image for off, and another for on. But in this case is just for indication (doesn't need touch).
A naive way, that works is:
Image { source: root.on ? "on.png" : "off.png" }
However, guess that is poor practice for performance? Assume the next image is reloaded from scratch, on each state change?Another way might be AnimatedSprite.currentFrame
https://doc.qt.io/qt-6/qml-qtquick-animatedsprite.html
A sprite, with both frames in the same image file, is elegant from a code and resources point of view. But working with x offsets, rather than z layers, seems error-prone for the graphic designer? Especially as the off/on graphics need to have pixel-perfect alignment.Another way might be Item states
https://doc.qt.io/qt-6/qml-qtquick-item.html#states-prop
That could change the Image source (but then has the same performance as the naive solution)
Or the states could toggle the visibility of two Image instances.Having two Image instances, and toggling their visibility, is probably the best way. It's not much code anyway. And could use states, or just bind visibility of both images to a bool property?
But just incase, is there any existing Qt QML component that associates images with states?
Thank you
-- Peter -
What is the best practice for creating a component, with different images, for off and on states?
Like a toggle switch, with one image for off, and another for on. But in this case is just for indication (doesn't need touch).
A naive way, that works is:
Image { source: root.on ? "on.png" : "off.png" }
However, guess that is poor practice for performance? Assume the next image is reloaded from scratch, on each state change?Another way might be AnimatedSprite.currentFrame
https://doc.qt.io/qt-6/qml-qtquick-animatedsprite.html
A sprite, with both frames in the same image file, is elegant from a code and resources point of view. But working with x offsets, rather than z layers, seems error-prone for the graphic designer? Especially as the off/on graphics need to have pixel-perfect alignment.Another way might be Item states
https://doc.qt.io/qt-6/qml-qtquick-item.html#states-prop
That could change the Image source (but then has the same performance as the naive solution)
Or the states could toggle the visibility of two Image instances.Having two Image instances, and toggling their visibility, is probably the best way. It's not much code anyway. And could use states, or just bind visibility of both images to a bool property?
But just incase, is there any existing Qt QML component that associates images with states?
Thank you
-- Peter -
If image performance is your only worry, you can always load them asynchronously.
States are made for making code more readable and maintainable, but it's a double edged sword.
If you use states for only one property then it's more cluttering the code than helping it be more readable.It's not bad to use any of the approaches, do whatever you deem the best.
-
Thank you, as I'll have several instances of this component, have come up with the following solution:
ImageStack { currentFrame: root.on sources: ["off.png", "on.png"] }
ImageStack.qml:
pragma ComponentBehavior: Bound import QtQuick Repeater { id: root required property int currentFrame required property list<string> sources model: root.sources Image { required property int index required property string modelData source: modelData visible: index == root.currentFrame } }