【问题标题】:How to drag an item outside a ListView in QML如何在 QML 中将项目拖到 ListView 之外
【发布时间】:2016-07-26 17:34:16
【问题描述】:

我正在开发一个 QML 应用程序,它基本上包含两个 ListView。我想将 QML 项目从一个 ListView 复制到另一个。我试图通过在委托中设置 Drag 属性来处理这个问题,但是当我拖动项目时,项目不能超出视图,我认为 Flickable 容器处理鼠标事件。
所以,我想尝试以下方法:

  • 创建一个与 ListView 重叠的鼠标区域
  • 通过调用 **createComponent() / createObject()** 创建一个新对象
  • 将此对象重新设置为鼠标区域
  • 处理鼠标区域中的鼠标事件直到放下

这个解决方案在我看来有点复杂,那么你有更好的方法来实现这个吗?


这是个坏主意,而且太复杂了。我想我有办法做到这一点:

  • ListView 的每个委托都有一个可以拖动的隐藏项,
  • 由于我的 ListView 在可重用组件中,我使用一个属性来传递一个更高的项目(这里是一个矩形,而不是 **MouseArea**),它可以用作拖动项目的父项,
  • 较高的项目包含两个 ListView(将来可能会更多),
  • 开始拖动时,项目设置为可见并使用 **State** 重新设置父项

所以,我错过了设置父母应该解决我的问题的观点。

【问题讨论】:

  • 我一直在研究一些想法,我已经 uploaded 将代码发送到 GitHub。我不知道您的列表模型-在上传的代码中非常简单-如果我正确理解了这个问题,那么我还不想将其发布为答案。希望这会有所帮助。
  • 感谢 sn-p,它与我想要实现的目标很接近,但该项目被移动而不是复制。我错过了拖动项目应该重新设置为更高级别项目的观点。我想我有一个灵感来自您的示例@Tarod 的解决方案。
  • 太棒了!请告诉我您是否希望我发布我的代码作为答案,或者您要发布自己的解决方案。编码愉快!
  • 是的,它可能很有用,你认为你可以添加评论来说明项目被移动而不是复制的事实吗?

标签: qt listview drag-and-drop qml


【解决方案1】:

下一个代码只是一个想法,但关键是在delegate 中为第一个ListView 添加一个MouseArea,以便用户可以将项目拖放到属于第二个ListView。

在本例中,model 非常简单,只是一个数字。并且当物品被丢弃时,它会从第一个ListView中移除:

listView.model.remove(listView.dragItemIndex)

只需删除该行代码即可复制项目而不是删除。

ma​​in.qml

import QtQuick 2.5
import QtQuick.Window 2.2

Window {
    visible: true
    width: 600
    height: 600

    Rectangle {
        id: root
        width: 400
        height: 400

        ListView {
            id: listView
            width: parent.width / 2
            height: parent.height

            property int dragItemIndex: -1

            model: ListModel {
                Component.onCompleted: {
                    for (var i = 0; i < 10; ++i) {
                        append({value: i});
                    }
                }
            }

            delegate: Item {
                id: delegateItem
                width: listView.width
                height: 50

                Rectangle {
                    id: dragRect
                    width: listView.width
                    height: 50
                    anchors.horizontalCenter: parent.horizontalCenter
                    anchors.verticalCenter: parent.verticalCenter
                    color: "salmon"
                    border.color: Qt.darker(color)

                    Text {
                        anchors.centerIn: parent
                        text: modelData
                    }

                    MouseArea {
                        id: mouseArea
                        anchors.fill: parent
                        drag.target: dragRect

                        drag.onActiveChanged: {
                            if (mouseArea.drag.active) {
                                listView.dragItemIndex = index;
                            }
                            dragRect.Drag.drop();
                        }
                    }

                    states: [
                        State {
                            when: dragRect.Drag.active
                            ParentChange {
                                target: dragRect
                                parent: root
                            }

                            AnchorChanges {
                                target: dragRect
                                anchors.horizontalCenter: undefined
                                anchors.verticalCenter: undefined
                            }
                        }
                    ]

                    Drag.active: mouseArea.drag.active
                    Drag.hotSpot.x: dragRect.width / 2
                    Drag.hotSpot.y: dragRect.height / 2
                }
            }
        }

        ListView {
            id: listView2
            width: parent.width / 2
            height: parent.height
            anchors.right: parent.right

            property int dragItemIndex: -1

            DropArea {
                id: dropArea
                anchors.fill: parent
                onDropped: {
                    listView2.model.append(listView.model.get(listView.dragItemIndex))
                    listView.model.remove(listView.dragItemIndex)
                    listView.dragItemIndex = -1;
                }
            }

            model: ListModel {
                Component.onCompleted: {
                    for (var i = 0; i < 1; ++i) {
                        append({value: i});
                    }
                }
            }

            delegate: Item {
                id: delegateItem2
                width: listView2.width
                height: 50

                Rectangle {
                    id: dragRect2
                    width: listView2.width
                    height: 50
                    anchors.horizontalCenter: parent.horizontalCenter
                    anchors.verticalCenter: parent.verticalCenter
                    color: "salmon"
                    border.color: Qt.darker(color)

                    Text {
                        anchors.centerIn: parent
                        text: modelData
                    }
                }
            }
        }
    }
}

【讨论】:

  • 我也尝试过类似的方法,但我的物品到处都掉了,我所做的只是限制掉到 DropArea
  • @GeorgeThomas 我想看看你的代码,以便帮助你并测试应用程序。
  • 我上传了一个问题,请查看stackoverflow.com/questions/40085507/…
猜你喜欢
  • 2018-09-15
  • 2013-01-05
  • 1970-01-01
  • 2016-12-08
  • 1970-01-01
  • 1970-01-01
  • 2015-06-04
  • 2016-03-26
  • 1970-01-01
相关资源
最近更新 更多