QML 拖放机制可以在不移动拖动项的情况下工作吗?
Can QML drag-and-drop mechanic work without drag item moving?
我有一个列表视图,上面有一个矩形。 ListView
的代表中有 DropArea
并且矩形在 Y 轴上启用了拖动及其相关属性(热点、目标)。
当我在 ListView 上上下移动矩形时,代表的 DropArea
正在注册 onEntered
信号。按预期工作。
但是,当矩形位于最顶部和底部坐标(list.y = 0
和 list.height
)时,我使用 SmoothedAnimation
上下滚动列表。所以矩形没有移动,列表代表的 DropArea
s 在它下面移动。在那种情况下,onEntered
没有注册,因为没有拖动,矩形完全静止,虽然它的 hotspot
正在进入和离开 DropArea
s,但没有交互。
这是因为拖动机制在移动时一直在发送事件,它进入的任何 DropArea
都可以注册该事件。就我而言,没有拖动,因此没有事件。
问:拖动事件可以手动激活吗?我能以某种方式模拟阻力吗?
我已经设法通过手动更改列表上方矩形的 hotSpot
属性 来引发拖动事件。 QML 拖动文档说:
Changes to hotSpot trigger a new drag move with the updated position.
所以每次 Listview
contentY
更改时我都会这样做(发生垂直滚动)
onContentYChanged:
{
rectangle.Drag.hotSpot.x += 0.0001
rectangle.Drag.hotSpot.x -= 0.0001
}
然而,事后看来,这是一个 'hacky' 解决方案。 hotSpot
属性 是 QPointF
class 属性 (link)。这意味着它可以使用各种方法(setX、setY、rx、ry..)进行设置。例如,这个:
rectangle.hotSpot += Qt.point(0,0)
或
rectangle.hotSpot = Qt.point(rectangle.hotSpot.x,rectangle.hotSpot.y)
理论上应该在 contentY
更改时通过重置 hotSpot
点来工作,但不幸的是测试显示它不会触发新的拖动动作。 (错误或有意,我不知道)
现在你们中一些更喜欢 Qt 和 QML 的人可能更了解这个问题以及如何正确解决这个问题,但是上面的解决方案对我有用,在测试了我能想到的所有内容以获得更清晰的解决方案之后,我决定了。
首先,您应该将 drag.target: parent
更改为 drag.target: this
。这样就不用拖动父项,而只拖动 mouseArea。之后,您应该从要拖动的项目中抓取图像。代码在这里:
Rectangle {
id: rec
width: 100
height: 100
Drag.active: dragArea.drag.active
Drag.dragType: Drag.Automatic
Drag.supportedActions: Qt.CopyAction
MouseArea {
id: dragArea
anchors.fill: parent
drag.target: this
onPressed:{
parent.grabToImage(function(result) {
parent.Drag.imageSource = result.url
})
}
}
}
我有一个列表视图,上面有一个矩形。 ListView
的代表中有 DropArea
并且矩形在 Y 轴上启用了拖动及其相关属性(热点、目标)。
当我在 ListView 上上下移动矩形时,代表的 DropArea
正在注册 onEntered
信号。按预期工作。
但是,当矩形位于最顶部和底部坐标(list.y = 0
和 list.height
)时,我使用 SmoothedAnimation
上下滚动列表。所以矩形没有移动,列表代表的 DropArea
s 在它下面移动。在那种情况下,onEntered
没有注册,因为没有拖动,矩形完全静止,虽然它的 hotspot
正在进入和离开 DropArea
s,但没有交互。
这是因为拖动机制在移动时一直在发送事件,它进入的任何 DropArea
都可以注册该事件。就我而言,没有拖动,因此没有事件。
问:拖动事件可以手动激活吗?我能以某种方式模拟阻力吗?
我已经设法通过手动更改列表上方矩形的 hotSpot
属性 来引发拖动事件。 QML 拖动文档说:
Changes to hotSpot trigger a new drag move with the updated position.
所以每次 Listview
contentY
更改时我都会这样做(发生垂直滚动)
onContentYChanged:
{
rectangle.Drag.hotSpot.x += 0.0001
rectangle.Drag.hotSpot.x -= 0.0001
}
然而,事后看来,这是一个 'hacky' 解决方案。 hotSpot
属性 是 QPointF
class 属性 (link)。这意味着它可以使用各种方法(setX、setY、rx、ry..)进行设置。例如,这个:
rectangle.hotSpot += Qt.point(0,0)
或
rectangle.hotSpot = Qt.point(rectangle.hotSpot.x,rectangle.hotSpot.y)
理论上应该在 contentY
更改时通过重置 hotSpot
点来工作,但不幸的是测试显示它不会触发新的拖动动作。 (错误或有意,我不知道)
现在你们中一些更喜欢 Qt 和 QML 的人可能更了解这个问题以及如何正确解决这个问题,但是上面的解决方案对我有用,在测试了我能想到的所有内容以获得更清晰的解决方案之后,我决定了。
首先,您应该将 drag.target: parent
更改为 drag.target: this
。这样就不用拖动父项,而只拖动 mouseArea。之后,您应该从要拖动的项目中抓取图像。代码在这里:
Rectangle {
id: rec
width: 100
height: 100
Drag.active: dragArea.drag.active
Drag.dragType: Drag.Automatic
Drag.supportedActions: Qt.CopyAction
MouseArea {
id: dragArea
anchors.fill: parent
drag.target: this
onPressed:{
parent.grabToImage(function(result) {
parent.Drag.imageSource = result.url
})
}
}
}