新的拖放机制在Qt-Quick中无法正常工作(Qt 5.3)

isn*_*bad 11 qt drag-and-drop qml qt-quick qt5

我试图实现拖动和使用新的QML类型的Qt 5.3下降Drag,DragEventDropArea.这是QML Drag类型文档中的原始示例,并进行了一些小的修改:

import QtQuick 2.2

Item {
    width: 800; height: 600

    DropArea {
        width: 100; height: 100; anchors.centerIn: parent

        Rectangle {
            anchors.fill: parent
            color: parent.containsDrag ? "red" : "green"
        }

        onEntered: print("entered");
        onExited: print("exited");
        onDropped: print("dropped");
    }

    Rectangle {
        x: 15; y: 15; width: 30; height: 30; color: "blue"

        Drag.active: dragArea.drag.active
        // Drag.dragType: Drag.Automatic
        Drag.onDragStarted: print("drag started");
        Drag.onDragFinished: print("drag finished");

        MouseArea {
            id: dragArea
            anchors.fill: parent
            drag.target: parent
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

预期行为:可以使用鼠标拖动小的蓝色矩形(拖动目标).如果拖过窗口中央较大的绿色矩形,此矩形会在离开时变为红色并返回绿色.此外,信号dragStarted,进入,退出,丢弃dragFinished在时间上发射和相应的信号处理程序打印出它们的消息.

经验丰富的行为:

取决于Drag.dragType(见上面的注释行):

  1. Drag.dragType未设置(默认为Drag.Internal):

    拖放按照描述工作,但只发出输入退出的信号.其他信号(dragStarted,dragFinisheddrop)被抑制.所以没有办法对下降做出反应DropArea.

  2. Drag.dragType设置为Drag.Automatic:

    现在所有信号都会发出,但蓝色矩形(拖动目标)不随鼠标移动.相反,鼠标光标会更改其形状以显示可能的放置目标.释放鼠标后,蓝色矩形跳转到最新的鼠标位置.

这两种变体都不令人满意.如何获取所有信号并仍能拖动拖动目标?不幸的是,文档是关于QML拖放的一切,但特别是关于不祥的Drag.dragType.

MrE*_*Sir 20

如果打开QQuickDrag源代码,看看之间的区别start(),这是使用的Drag.Internal,并且startDrag()它使用的Drag.Automatic,差异是很明显的. start()设置事件更改侦听器,然后使用它来更新附加对象的位置. startDrag()不这样做.

为什么这样工作?我不知道!QtQuick 2拖放文档肯定有改进的余地.

有一个相当简单的解决方法:从两个世界中获取最佳效果.使用Drag.Automatic,但不是设置Drag.active,调用start()drop()手动.它不会调用Drag.onDragStarted(),Drag.onDragFinished()但你基本上通过听取改变来获得免费MouseAreadrag.active.

这是运作中的概念:

import QtQuick 2.0

Item {
    width: 800; height: 600

    DropArea {
        width: 100; height: 100; anchors.centerIn: parent

        Rectangle {
            anchors.fill: parent
            color: parent.containsDrag ? "red" : "green"
        }

        onEntered: print("entered");
        onExited: print("exited");
        onDropped: print("dropped");
    }

    Rectangle {
        x: 15; y: 15; width: 30; height: 30; color: "blue"

        // I've added this property for simplicity's sake.
        property bool dragActive: dragArea.drag.active

        // This can be used to get event info for drag starts and 
        // stops instead of onDragStarted/onDragFinished, since
        // those will neer be called if we don't use Drag.active
        onDragActiveChanged: {
            if (dragActive) {
                print("drag started")
                Drag.start();
            } else {
                print("drag finished")
                Drag.drop();
            }
        }

        Drag.dragType: Drag.Automatic

        // These are now handled above.
        //Drag.onDragStarted: print("drag started");
        //Drag.onDragFinished: print("drag finished");

        MouseArea {
            id: dragArea
            anchors.fill: parent
            drag.target: parent
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我意识到这不是一个完全令人满意的解决方案,但它确实符合您的预期行为.

该解决方案提供:

  • 所有所需事件的通知:拖动开始,拖动完成,输入拖动区域,退出拖动区域,以及拖动拖动区域.
  • 拖动动画由QtQuick自动处理.正方形不会像运行示例代码时那样冻结Drag.Automatic.

它没有提供什么:

  • 解释为什么QtQuick的拖放功能以这种方式工作,或者它是否甚至是开发人员的预期行为.目前的文件似乎含糊不清.