Slider元素将目标值重置为滑块的最小值

时间:2016-01-23 15:08:59

标签: qt binding qml qtquick2 qtquickcontrols

这个问题有一个自包含的例子:

Rectangle {
    id: rect
    width: 200
    height: 200
    property real v : 50
    onVChanged: console.log(v)
    Button {
        onClicked: scomp.createObject(rect)
    }
    Component {
        id: scomp
        Rectangle {
            id: sli
            anchors.fill: parent
            Column {
                Slider {
                    width: 200
                    minimumValue: 10
                    maximumValue: 100
                    value: rect.v
                    onValueChanged: rect.v = value
                }
                Button {
                    onClicked: sli.destroy()
                }
            }
        }
    }
}

基本上,每次创建滑块组件以修改v时,它都会将其设置为滑块的最小值。请注意,滑块仍然可以正常工作以修改该值,并且滑块关闭后v将保持其正确的值,但是当它再次打开时,该值会再次损坏。

为什么会发生这种情况,如何预防呢?看起来由于一些可解释的原因,滑块的value属性暂时采用其minimumValue值,但这看起来不像是适当的行为。也许是个bug?即使在设置最小值之前移动了value: rect.v,滑块也从未真正采用正确的初始值。

2 个答案:

答案 0 :(得分:1)

这不是Slider中的错误,而是您对它的使用:

onValueChanged: rect.v = value

如果你再添加一些调试语句:

qml: maximumValue = 100 value = 0
qml: minimumValue = 10 value = 10
qml: value = 10
qml: v = 10
void __cdecl QQuickRangeModel::setValue(double) 10
qml: in Component.onCompleted of Slider: value = 10 minimumValue = 10 maximumValue = 100

在它有机会完成加载之前,您已经将value分配给v。正确的解决方案取决于您的要求,您还没有提到。例如,一种解决方案是在Slider中指定默认值,并将v绑定到value

v: slider ? slider.value : 0
  

似乎执行顺序设计不佳

How would you design it

答案 1 :(得分:-1)

如果没有深入研究Slider元素的实现,似乎实现顺序设计不合理,初始值为0.0,因此将最小值设置为更高值也会推高该值。如果值被绑定到高于最小值的值并不重要,由于评估的顺序,当设置最小值时值始终为0.0,因此在此格式中,目标值将始终被损坏到滑块的最低价值。

我提出的解决方案通过延迟目标值绑定来避免这种行为,它可以工作,但它不是那么漂亮,所以我仍然对其他解决方案持开放态度,同时Qt人 - 如果你看到这个你可能想要修复Slider

Slider {
    width: 200
    minimumValue: 10
    maximumValue: 100
    value: rect.v
    Component.onCompleted: valueChanged.connect(function(){ rect.v = value})
}

此格式最初仍然将滑块值推到最小值,但此时设置目标值的绑定尚不存在,只有在滑块值采用正确值后才会创建。