问题
I am using Qt 5.4.1. I have made a custom slider element to be used in other qml components like so:
Slider.qml
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Controls.Styles 1.3
Item {
id: root
width: 150
height: 30
property int val: slider.value
property int maxVal: slider.maximumValue
property int minVal: slider.minimumValue
property int step: slider.stepSize
Slider {
id: slider
anchors.margins: 20
stepSize: step
maximumValue: maxVal
minimumValue: minVal
style: customStyle
// onValueChanged: print("From Slider.qml" ,value)
}
Component {
id: customStyle
SliderStyle {
handle: Rectangle {
width: 20
height: 12
antialiasing: true
color: Qt.lighter("#468bb7", 1.2)
}
groove: Item {
implicitHeight: root.height
implicitWidth: root.width
Rectangle {
height: 8
width: parent.width
anchors.verticalCenter: parent.verticalCenter
color: "#847878"
opacity: 0.8
Rectangle {
antialiasing: true
radius: 1
color: "#1a0d0d"
height: parent.height
width: parent.width * control.value / control.maximumValue
}
}
}
}
}
}
And in another file test.qml
I am using this slider like so
test.qml
import QtQuick 2.3
Rectangle {
id: test
width: 640; height: 480
Slider {
id: slider
width: 300
height: 30
anchors.centerIn: parent
maxVal: 1000
minVal: 0
step: 50
val: 500 // when commented out, onValChanged is triggered on sliding
onValChanged: print(val)
}
}
I want to set the slider to an initial value when instantiated in test.qml
, using the property val
. But when I set initial value, onValChanged
does not get triggered when sliding the slider. But when I comment that line out (val: 500
), onValChanged
is triggered when the slider is slid, but the slider starts with initial value of 0 which I don't want. I don't understand what I am doing wrong here!
回答1:
The setting of the property val
to a specific value overrides the binding, as defined in your slider
component. Once the binding is lost, any update of the slider is not delivered to val
resulting in the behaviour you experienced. On the other way around, if you don't set the property the binding is maintained, i.e. as the slider value changes the value of val
changes accordingly, triggering the signal.
That's not the way to go in this case, also because you are adding a set of properties which simply exposes inner properties of Slider
. Just use properties alias:
Property aliases are properties which hold a reference to another property. Unlike an ordinary property definition, which allocates a new, unique storage space for the property, a property alias connects the newly declared property (called the aliasing property) as a direct reference to an existing property (the aliased property).
Rewrite your properties inside Slider.qml
as follows:
property alias val: slider.value
property alias maxVal: slider.maximumValue
property alias minVal: slider.minimumValue
property alias step: slider.stepSize
This way val
is slider.value
and setting it to 500
directly affect the slider without breaking any binding.
On a sidenote, you can also for example write
property alias maximumValue: slider.maximumValue
i.e. expose inner properties with their very same name to maintain the consistency in API naming.
来源:https://stackoverflow.com/questions/29097133/how-to-set-initial-value-of-a-custom-slider-in-qml