如何解决如何在可重用的 QML 组件中保留绑定?
我试图在我的滑块组件中保留双重绑定逻辑,使其行为与内置 Slider
相同:
import QtQuick 2.0
import QtQuick.Window 2.0
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
Window {
ColumnLayout {
SimpleSlider { id: sslider0; value: .3 }
SimpleSlider { id: sslider1; value: 1 - sslider0.value }
Slider { id: slider0; value: .3 }
Slider { id: slider1; value: 1 - slider0.value }
}
}
不幸的是,它没有:
这是我的SimpleSlider.qml
:
import QtQuick 2.4
Item {
id: simple_slider
property real value: .5
property real min_value: 0
property real max_value: 1
width: childrenRect.width
height: childrenRect.height
function linear(a,b,x) { return (x - a) / (b - a) }
function mix(a,x) { return a * (1 - x) + b * x }
FontMetrics { id: fontMetrics }
Rectangle {
id: main_box
width: Math.max(txt_label.width + 10,50)
height: fontMetrics.height + 10
radius: 2
color: "darkgrey"
}
Rectangle {
id: filled_box
width: linear(min_value,max_value,value) * main_box.width
height: main_box.height
radius: main_box.radius
color: "orange"
}
Text {
id: txt_label
text: value.toFixed(3)
anchors.centerIn: main_box
}
MouseArea {
property real xval: simple_slider.value
id: drag_slider
anchors.fill: parent
onPositionChanged: xval = get_value_from_pos(mouse.x)
function get_value_from_pos(x) {
var v = Math.min(Math.max(linear(0,main_box.width,x),0),1)
return mix(min_value,v)
}
}
Binding {
target: simple_slider
property: "value"
value: drag_slider.xval
}
}
原因很明显:我在这里覆盖了绑定:onPositionChanged: xval = get_value_from_pos(mouse.x)
(并由 QT_LOGGING_RULES="qt.qml.binding.removal.info=true"
确认)
虽然我确定了问题的核心,但我不确定如何处理。
可能有一种扭曲的设计,我会使用位置更改状态将其转换为基于声明的形式,但是当我的滑块也接受来自 TextInput
(这将需要在其 onAccepted
回调中以类似方式更新值)。
解决方法
JarMan 的提示很好。我试图解决你的例子中的双向绑定问题,但没有运气。因此,我向您展示了样式标准滑块:
这是我的
SimpleSlider.qml
:
import QtQuick 2.15
import QtQuick.Templates 2.15 as T
T.Slider {
id: slider
width: 200
height: 40
background: Rectangle {
color: "darkgrey"
Rectangle {
width: slider.visualPosition * parent.width
height: parent.height
color: "orange"
}
}
Text {
text: slider.value.toFixed(3)
anchors.centerIn: slider
}
}
,
编辑 SimpleSlider.qml:
import QtQuick 2.15
import QtQml 2.15
Item {
id: simple_slider
property real value: .5
property real tempValue: value
property real min_value: 0
property real max_value: 1
width: childrenRect.width
height: childrenRect.height
function linear(a,b,x) { return (x - a) / (b - a) }
function mix(a,x) { return a * (1 - x) + b * x }
FontMetrics { id: fontMetrics }
Rectangle {
id: main_box
width: Math.max(txt_label.width + 10,50)
height: fontMetrics.height + 10
radius: 2
color: "darkgrey"
}
Rectangle {
id: filled_box
width: linear(min_value,max_value,tempValue) * main_box.width
height: main_box.height
radius: main_box.radius
color: "orange"
}
Text {
id: txt_label
text: tempValue.toFixed(3)
anchors.centerIn: main_box
}
MouseArea {
///property real xval: simple_slider.value
id: drag_slider
anchors.fill: parent
onPositionChanged: tempValue = get_value_from_pos(mouse.x)
onReleased: tempValue = Qt.binding(function() { return value })
function get_value_from_pos(x) {
var v = Math.min(Math.max(linear(0,main_box.width,x),0),1)
return mix(min_value,v)
}
}
Binding on value {
when: drag_slider.pressed
value: tempValue
restoreMode: Binding.RestoreBinding
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。