上下文
我正在尝试使用QML创建平铺地图而不使用QtLocation。我正在尝试设计应用程序,以便只加载基本的磁贴。这是我提出的策略。
每个图块为256x256像素。切片放置在具有嵌套Repeater的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++;
}
}
问题
我的网格的移动由MouseArea控制,其中drag.target设置为它。似乎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> gt; 100,确实设置了x = 0。然而,这是因为盒子的实际价值仍然是100+。如果再次向左移动框(x <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;
}
}
}
}
}
答案 0 :(得分:0)
更新代码的问题是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"
}
}
}