QML在被MouseArea拖动时无法更改项目的位置
Posted
技术标签:
【中文标题】QML在被MouseArea拖动时无法更改项目的位置【英文标题】:QML Unable to change position of item while being dragged by MouseArea 【发布时间】:2018-04-23 06:37:28 【问题描述】:上下文
我正在尝试使用 QML 创建平铺地图而不使用 QtLocation。我正在尝试设计应用程序,以便只加载基本的图块。这是我想出的策略。
每个图块为 256x256 像素。瓦片放置在具有嵌套中继器的 Grid 类中。 xOffset 确定应加载到网格中的图块。
Grid
id: mapgrid
rows: 6
columns: 9
spacing: 1
Repeater
model: 6
Repeater
model: 9
property int outerIndex: index
Tile
imgsrc: "image://provider/" + maprect.zoomLevel + '/' + (index + maprect.xOffset) + '/' + (outerIndex+maprect.yOffset)
当网格向左移动 256 像素时,应该加载一组新的图块。这可以通过更改偏移值来实现。然后我可以再次将网格移动 256 像素,使其回到视图中。
onXChanged:
if(x <= -512)
maprect.x = -256;
maprect.xOffset++;
问题
我的网格的移动由设置为 drag.target 的 MouseArea 控制。似乎 MouseArea 控制坐标,直到释放鼠标。这是一个简单的例子:
import QtQuick 2.9
import QtQuick.Window 2.2
Window
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Text
z:1
text: "X: " + rect.x
MouseArea
id:marea
anchors.fill: rect
drag.target: rect
Rectangle
id: rect
height: 256
width: 256
color: "red"
onXChanged:
if(x > 100)
x = 0;
如果您将框移到 x > 100 之后,则确实设置了 x=0。然而那是因为盒子的实际价值仍然是 100+。如果你再次将盒子向左移动(x
我正在寻找的是另一种加载图块的方法或修复 MouseArea 问题,这样我就可以在项目被 MouseArea 拖动时实际更改它的位置。
另外,我是否可以实现不同版本的 MouseArea,以便我可以在较低的抽象层上处理这个问题?
更新
我已经能够在一定程度上达到我想要的效果。它似乎工作正常,但 QML 正在检测绑定循环。
import QtQuick 2.9
import QtQuick.Window 2.2
Window
id: wind
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Rectangle
id: wrapper
height: wind.height
width: wind.width
MouseArea
id:marea
anchors.fill: wrapper
//drag.target: rect
property int initialX: 0
property int iniMouseX;
onEntered:
initialX = rect.x
iniMouseX = mouseX
console.log ("set")
Rectangle
id: rect
height: 256
width: 256
border.color: "green"
x: marea.initialX + (marea.mouseX - marea.iniMouseX)
color: "red"
onXChanged:
if(rect.x > 200)
marea.initialX -= 200;
https://imgur.com/a/zmu5eiO
【问题讨论】:
除了你还有什么结果?如果 rect 拖出 x:100,即使鼠标仍未释放,您希望 rect 停留在 x:0 直到再次按下它? @Jiu 我想把矩形移到x = 0,然后我可以继续拖动它直到x > 100,回到x = 0等等 【参考方案1】:更新代码的问题是initialX
与rect.x
绑定,所以如果rect.x
被更新它会调用onXChanged
,如果rect.x > 200
会再次更新initialX
,这将变成无限环形。
所以在这里修复它是解决方案,让事件像流程一样:
Window
id: wind
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Rectangle
id: wrapper
height: wind.height
width: wind.width
MouseArea
id:marea
anchors.fill: wrapper
//drag.target: rect
property int initialX: 0
property int iniMouseX;
onEntered:
initialX = rect.x
iniMouseX = mouseX
console.log ("set")
onMouseXChanged:
if(rect.x > 200)
marea.initialX -= 200;
rect.x = marea.initialX + (marea.mouseX - marea.iniMouseX)
Rectangle
id: rect
height: 256
width: 256
border.color: "green"
color: "red"
【讨论】:
感谢您的回答,但这不是我想要的。这是一个 gif 来说明我想要什么:imgur.com/a/zmu5eiO @gxxexx 我修复了 update 代码错误,看看新答案。 这正是我要找的,感谢您解释并帮助我解决绑定循环问题!以上是关于QML在被MouseArea拖动时无法更改项目的位置的主要内容,如果未能解决你的问题,请参考以下文章
QML TableView 鼠标区域不会将点击传播到选择模型