首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >新的拖放机制在Qt-Quick中不能像预期的那样工作(QT5.3)

新的拖放机制在Qt-Quick中不能像预期的那样工作(QT5.3)
EN

Stack Overflow用户
提问于 2014-07-02 13:23:57
回答 2查看 6.4K关注 0票数 15

我尝试使用新的QML类型DragDragEventDropArea实现QT5.3中的拖放。这是来自类型的原始示例,并做了一些小修改:

代码语言:javascript
复制
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
        }
    }
}

预期行为:可以用鼠标拖动小蓝色矩形(拖动目标)。如果拖动窗口中心较大的绿色矩形,则该矩形在离开时会变成红色,然后返回到绿色。此外,输入、退出、删除和dragStarted的信号被及时发出,相应的信号处理程序输出它们的消息。

经验行为

取决于Drag.dragType (请参阅上面的注释行):

  1. 未设置Drag.dragType (默认为Drag.Internal): 拖放按描述工作,但只发出输入和退出的信号。其他信号(dragStarted、dragFinished和丢弃)被抑制。因此,没有办法对DropArea的下降作出反应。
  2. Drag.dragType设置为Drag.Automatic: 所有的信号现在都发出了,但是蓝色矩形(拖动目标)不会随鼠标移动。相反,鼠标光标改变其形状,以可视化可能的拖放目标。鼠标释放后,蓝色矩形跳转到鼠标的最新位置。

这两种变体都不讨人喜欢。我怎样才能得到所有的信号,并且仍然能够拖动拖动目标?不幸的是,这些文档对QML中的拖放非常清楚,特别是关于不祥的Drag.dragType

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-07-14 05:06:20

如果打开源代码并查看Drag.Internal使用的start()Drag.Automatic使用的startDrag()之间的差异,差异是非常明显的。设置事件更改侦听器,然后将其用于附加对象的更新职位不会这么做

它为什么会这样工作?我没有头绪!QtQuick 2拖放文档在这里肯定有改进的余地。

有一个相当简单的解决办法:从这两个世界中取得最好的结果。使用Drag.Automatic,但不要设置Drag.active,而是手动调用start()drop()。它不会调用Drag.onDragStarted()Drag.onDragFinished(),但通过监听MouseArea's drag.active的更改,您基本上可以免费获得它们。

以下是实际行动中的概念:

代码语言:javascript
复制
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
        }
    }
}

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

该解决方案提供:

  • 所有所需事件的通知:“开始拖动”、“完成拖动”、“输入拖动区域”、“退出拖动区域”和“拖放区域”。
  • 拖动动画由QtQuick自动处理。在使用Drag.Automatic运行示例代码时,方块不像运行时那样冻结。

它没有提供的东西:

  • 说明为什么QtQuick的拖放功能是这样工作的,或者它是否是开发人员想要的行为。目前的文档似乎模棱两可。
票数 28
EN

Stack Overflow用户

发布于 2014-07-08 06:06:52

我自己也遇到了这个问题(使用QT5.2,但也存在同样的问题)。我在X轴上有个“滑块盒”,我只想知道拖曳什么时候完成.而不是对一路上每一个位置的变化做出反应。我的解决办法是侵入状态/转换,使用一个ScriptAction来提供逻辑。这是用于模拟对"onDragFinished“信号的响应的简化版本。因此,虽然它没有覆盖所有拖放信号,但它可能会使您指向正确的方向。

代码语言:javascript
复制
Rectangle {
    id: sliderControl

    height: coordinates.height
    width: 80
    color: "#F78181"
    border.color: "#FE2E2E"
    border.width: 1
    opacity: 0.4

    MouseArea {
        id: mouseArea
        anchors.fill: parent
        drag.target: sliderControl
        drag.axis: Drag.XAxis
        drag.minimumX: 0
        drag.maximumX: view.width - sliderControl.width
        hoverEnabled: true
    }

    states: [
        State {
            name: "dragging"
            when: mouseArea.drag.active
        },
        State {
            name: "finished_dragging"
            when: !mouseArea.drag.active
        }
    ]

    transitions: [
        Transition {
            from: "dragging"
            to: "finished_dragging"
            ScriptAction {
                script: console.log("finished dragging script");
            }
        }
    ]
}

ps -我知道这样一个‘解决办法’不符合赏金参数的条件,但当我在这个问题上寻求帮助时,我非常沮丧地发现只有你的问题(没有解决方案)。希望任何在这条道路上跌跌撞撞的人都会发现这是有用的。不幸的是,我也不知道QML的Drag.dragType是怎么回事。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24532317

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档