Qml - 如何停止将矩形拖到它的外部 parent
Qml - How to stop a rectangle dragging outside it's parent
我正在使用 qml 创建一个可调整大小的矩形,可以将其拖到 parent 窗格内,但不能拖到外面(图 1)。当我调整它的大小时使用左上角的手柄,效果很好,无法在 parent 之外调整大小(图 2)。但是当我拖动整个矩形时,它可以被拖到它的 parent 之外(图 3)。我的代码试图对两者使用相同的逻辑,即一旦矩形的左侧到达它的 parent 的左侧,它就会取消拖动。调整大小效果很好,但拖动矩形时效果不佳。我做错了什么?
Pane {
id: compPane
implicitHeight: imageListModel.reqViewHeight
implicitWidth: imageListModel.reqViewWidth
leftPadding: 0
topPadding: 0
clip: true
background: Rectangle{
id: backgroundRect
anchors.fill: parent
color: "gray"
border.color: "black"
border.width: 6
}
// Resizable rectangle that can be dragged
Rectangle {
id: indRect
x:parent.width / 4
y: parent.height / 4
width: parent.width / 2
height: parent.width / 2
border {
width: 2
color: "steelblue"
}
color: "#354682B4"
MouseArea {
id: indImagesDragArea
anchors.fill: parent
anchors.margins: 8
drag.target: parent
onPositionChanged: {
if (drag.active){
if (indRect.x <= 0 + backgroundRect.border.width)
Drag.cancel()
if (indRect.x + indRect.width >= (compPane.width - backgroundRect.border.width) )
Drag.cancel()
}
}
}
// Top Left handle - works well
Rectangle {
width: 15
height: 15
color: "steelblue"
anchors.verticalCenter:parent.top
anchors.horizontalCenter: parent.left
MouseArea {
anchors.fill: parent
cursorShape: Qt.SizeFDiagCursor
drag{ target: parent; axis: Drag.XAndYAxis }
onPositionChanged: {
if(drag.active){
//var delta = Math.max(mouseX, mouseY)
var newWidth = indRect.width - mouseX
var newHeight = indRect.height - mouseY;
if (newWidth < width || newHeight < height)
return
if (indRect.x <= 0 + backgroundRect.border.width && mouseX < 0){
Drag.cancel()
indRect.x = 0 + backgroundRect.border.width
}
else {
indRect.width = newWidth
indRect.x = indRect.x + mouseX
}
if (indRect.y <= 0 + backgroundRect.border.width && mouseY < 0){
Drag.cancel()
indRect.y = 0 + backgroundRect.border.width
}
else{
indRect.height = newHeight
indRect.y = indRect.y + mouseY
}
}
}
}
}
}
}
您可以尝试使用 drag.minimum 和 drag.maximum 的 属性。
请参阅文档:
https://doc.qt.io/qt-5/qml-qtquick-mousearea.html#drag.threshold-prop
Drag.cancel()
实际上用于实现拖放类型的交互。在这种情况下,对它的调用什么都不做,因为您实际上从未启动过这些序列之一。如果您注释掉对 Drag.cancel()
.
的调用,则您的左上角句柄示例可以正常工作
为什么你的左上角的例子有效是因为你限制了位置更新的 x 和 y 以通过 indRect.x
和 indRect.y
的显式更新将它们剪辑到场景中。您只需要为主要的拖动场景实现相同的技术。
例如:
onPositionChanged: {
if (drag.active){
if (indRect.x <= 0 + backgroundRect.border.width)
indRect.x = 0 + backgroundRect.border.width;
if (indRect.x + indRect.width >= (compPane.width - backgroundRect.border.width) )
indRect.x = compPane.width - backgroundRect.border.width - indRect.width;
}
}
我正在使用 qml 创建一个可调整大小的矩形,可以将其拖到 parent 窗格内,但不能拖到外面(图 1)。当我调整它的大小时使用左上角的手柄,效果很好,无法在 parent 之外调整大小(图 2)。但是当我拖动整个矩形时,它可以被拖到它的 parent 之外(图 3)。我的代码试图对两者使用相同的逻辑,即一旦矩形的左侧到达它的 parent 的左侧,它就会取消拖动。调整大小效果很好,但拖动矩形时效果不佳。我做错了什么?
Pane {
id: compPane
implicitHeight: imageListModel.reqViewHeight
implicitWidth: imageListModel.reqViewWidth
leftPadding: 0
topPadding: 0
clip: true
background: Rectangle{
id: backgroundRect
anchors.fill: parent
color: "gray"
border.color: "black"
border.width: 6
}
// Resizable rectangle that can be dragged
Rectangle {
id: indRect
x:parent.width / 4
y: parent.height / 4
width: parent.width / 2
height: parent.width / 2
border {
width: 2
color: "steelblue"
}
color: "#354682B4"
MouseArea {
id: indImagesDragArea
anchors.fill: parent
anchors.margins: 8
drag.target: parent
onPositionChanged: {
if (drag.active){
if (indRect.x <= 0 + backgroundRect.border.width)
Drag.cancel()
if (indRect.x + indRect.width >= (compPane.width - backgroundRect.border.width) )
Drag.cancel()
}
}
}
// Top Left handle - works well
Rectangle {
width: 15
height: 15
color: "steelblue"
anchors.verticalCenter:parent.top
anchors.horizontalCenter: parent.left
MouseArea {
anchors.fill: parent
cursorShape: Qt.SizeFDiagCursor
drag{ target: parent; axis: Drag.XAndYAxis }
onPositionChanged: {
if(drag.active){
//var delta = Math.max(mouseX, mouseY)
var newWidth = indRect.width - mouseX
var newHeight = indRect.height - mouseY;
if (newWidth < width || newHeight < height)
return
if (indRect.x <= 0 + backgroundRect.border.width && mouseX < 0){
Drag.cancel()
indRect.x = 0 + backgroundRect.border.width
}
else {
indRect.width = newWidth
indRect.x = indRect.x + mouseX
}
if (indRect.y <= 0 + backgroundRect.border.width && mouseY < 0){
Drag.cancel()
indRect.y = 0 + backgroundRect.border.width
}
else{
indRect.height = newHeight
indRect.y = indRect.y + mouseY
}
}
}
}
}
}
}
您可以尝试使用 drag.minimum 和 drag.maximum 的 属性。 请参阅文档:
https://doc.qt.io/qt-5/qml-qtquick-mousearea.html#drag.threshold-prop
Drag.cancel()
实际上用于实现拖放类型的交互。在这种情况下,对它的调用什么都不做,因为您实际上从未启动过这些序列之一。如果您注释掉对 Drag.cancel()
.
为什么你的左上角的例子有效是因为你限制了位置更新的 x 和 y 以通过 indRect.x
和 indRect.y
的显式更新将它们剪辑到场景中。您只需要为主要的拖动场景实现相同的技术。
例如:
onPositionChanged: {
if (drag.active){
if (indRect.x <= 0 + backgroundRect.border.width)
indRect.x = 0 + backgroundRect.border.width;
if (indRect.x + indRect.width >= (compPane.width - backgroundRect.border.width) )
indRect.x = compPane.width - backgroundRect.border.width - indRect.width;
}
}