上下文
我正在尝试使用QML创建瓷砖地图而无需使用QTLocation。我正在尝试设计应用程序,以便只加载必需的瓷砖。这是我提出的策略。
每个瓷砖为256x256 px。瓷砖放在带有嵌套的中继器的网格类中。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++;
}
}
问题
我的网格的移动由带有拖动的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&lt; 100(,您会发现该框以其实际X值返回。抱歉,如果听起来令人困惑,那么自己就更容易理解。
我正在寻找的是加载瓷砖或修复Mousearea问题的替代方法,以便我可以在物品被Mousearea拖动时实际上更改其位置。
另外,我是否有可能实现不同版本的Mousearea,以便我可以在较低的抽象中处理这个问题?
update
我已经能够在一定程度上实现我想要的效果。它似乎工作正常,但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://i.stack.imgur.com/e5qqh.jpg
更新的代码的问题是用rect.x
绑定initialX
,因此,如果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"
}
}
}