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】:

更新代码的问题是initialXrect.x绑定,所以如果rect.x被更新它会调用onXChanged,如果rect.x &gt; 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 指针处理程序和处理抓取更改

QML TableView 鼠标区域不会将点击传播到选择模型

QML事件处理 八

QML:在 C++ 中获取 MouseArea 的鼠标事件

QML:没有调用 Rectangle 的 MouseArea 上的 onClicked 方法

QML-在 MouseArea 中未检测到右键单击