137 lines
4.7 KiB
QML
137 lines
4.7 KiB
QML
import QtQuick
|
|
import QtQuick.Controls
|
|
import QtQuick.Layouts
|
|
|
|
Item {
|
|
id: control
|
|
|
|
property var value: Qt.rect(0, 0, 0, 0)
|
|
property int decimals: 1
|
|
implicitHeight: 25
|
|
implicitWidth: 240
|
|
|
|
signal asValueChanged(value: var)
|
|
|
|
function setValue(newValue) {
|
|
if (!control.value ||
|
|
Math.abs(control.value.x - newValue.x) > 0.000001 ||
|
|
Math.abs(control.value.y - newValue.y) > 0.000001 ||
|
|
Math.abs(control.value.width - newValue.width) > 0.000001 ||
|
|
Math.abs(control.value.height - newValue.height) > 0.000001) {
|
|
value = newValue
|
|
asValueChanged(value)
|
|
}
|
|
}
|
|
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
spacing: 2
|
|
|
|
Repeater {
|
|
id: repeater
|
|
model: [
|
|
{ label: "X", prop: "x", validator: [-999999, 999999] },
|
|
{ label: "Y", prop: "y", validator: [-999999, 999999] },
|
|
{ label: "W", prop: "width", validator: [0, 999999] },
|
|
{ label: "H", prop: "height", validator: [0, 999999] }
|
|
]
|
|
|
|
RowLayout {
|
|
id: inputRow
|
|
spacing: 2
|
|
Layout.alignment: Qt.AlignVCenter
|
|
|
|
property string propertyName: modelData.prop
|
|
property var textField: inputField
|
|
|
|
Label {
|
|
text: modelData.label + ":"
|
|
font.pixelSize: 10
|
|
}
|
|
|
|
TextField {
|
|
id: inputField
|
|
Layout.preferredWidth: 60
|
|
Layout.preferredHeight: 22
|
|
text: control.value ? control.value[modelData.prop].toFixed(control.decimals) : "0.0"
|
|
font.pixelSize: 9
|
|
padding: 2
|
|
selectByMouse: true
|
|
|
|
// 双击全选的处理
|
|
MouseArea {
|
|
id: fieldMouseArea
|
|
anchors.fill: parent
|
|
propagateComposedEvents: true
|
|
acceptedButtons: Qt.LeftButton
|
|
cursorShape: Qt.IBeamCursor
|
|
|
|
onDoubleClicked: function(mouse) {
|
|
parent.selectAll()
|
|
parent.forceActiveFocus()
|
|
mouse.accepted = true
|
|
}
|
|
|
|
onClicked: function(mouse) {
|
|
// 单击时设置焦点但不全选
|
|
parent.forceActiveFocus()
|
|
mouse.accepted = false
|
|
}
|
|
}
|
|
|
|
onActiveFocusChanged: {
|
|
if (activeFocus) {
|
|
// 如果不是双击触发的焦点变化,就全选文本
|
|
if (!fieldMouseArea.containsPress) {
|
|
selectAll()
|
|
}
|
|
}
|
|
}
|
|
|
|
validator: DoubleValidator {
|
|
bottom: modelData.validator[0]
|
|
top: modelData.validator[1]
|
|
decimals: 2
|
|
}
|
|
|
|
background: Rectangle {
|
|
border.color: parent.activeFocus ? "#0066cc" : "#999999"
|
|
border.width: 1
|
|
radius: 1
|
|
}
|
|
|
|
onEditingFinished: {
|
|
var val = parseFloat(text)
|
|
if (!isNaN(val) && control.value) {
|
|
var newRect = Qt.rect(
|
|
modelData.prop === "x" ? val : control.value.x,
|
|
modelData.prop === "y" ? val : control.value.y,
|
|
modelData.prop === "width" ? val : control.value.width,
|
|
modelData.prop === "height" ? val : control.value.height
|
|
)
|
|
control.setValue(newRect)
|
|
} else {
|
|
text = control.value ? control.value[modelData.prop].toFixed(control.decimals) : "0.0"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Item { Layout.fillWidth: true }
|
|
}
|
|
|
|
onValueChanged: {
|
|
if (!value) return
|
|
|
|
// 通过 Repeater 的 itemAt 方法安全访问
|
|
var props = ["x", "y", "width", "height"]
|
|
for (var i = 0; i < props.length; i++) {
|
|
var item = repeater.itemAt(i)
|
|
if (item && item.textField && !item.textField.activeFocus) {
|
|
item.textField.text = value[props[i]].toFixed(decimals)
|
|
}
|
|
}
|
|
}
|
|
}
|