0

有一个自包含的问题示例:

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值,但这看起来不像是适当的行为。也许是一个错误?滑块永远不会真正假定正确的初始值,即使value: rect.v在设置最小值之前移动。

4

2 回答 2

2

这不是 中的错误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

在它有机会完成加载之前,您已经将其分配valuev. 正确的解决方案取决于您没有提到的要求。例如,一种解决方案是指定默认值Slider,然后绑定vvalue

v: slider ? slider.value : 0

执行顺序似乎设计得很糟糕

你会如何设计它


要使用 Qt Quick Controls 2 中的Slider更新此答案,您应该使用moved() 信号来响应被拖动的滑块。用于onValueChanged此目的通常会导致问题。

于 2016-01-23T19:01:43.420 回答
-1

没有深入研究Slider元素的实现,似乎实现顺序设计得不好,初始值为0.0,因此将最小值设置为更高的值也会推高该值。并且 value 是否绑定到高于最小值也没有关系,由于评估的顺序,设置最小值时 value 始终为 0.0,因此在这种格式下,目标值将始终损坏为滑块的最小值。

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

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

这种格式仍然最初将滑块值推到最小值,但此时设置目标值的绑定还不存在,它仅在滑块值假定正确值后创建。

于 2016-01-23T16:59:29.120 回答