首页 > 解决方案 > MouseArea 移动时无法更新 mouseContains 属性

问题描述

我有一个问题,即MouseAreacontainsMouse属性在动画后无法正确更新自身。

下面我包含了一个代码片段,希望能说明我的观点:

import QtQuick 2.10

Item {
    id: root

    width: 500
    height: 240
    visible: true

    ListView {
        id: view

        anchors.fill: parent
        anchors.margins: 20
        orientation: ListView.Horizontal
        spacing: 20

        delegate: Rectangle {
            width: 100
            height: 200
            color: "black"
            radius: 10

            Rectangle {
                width: 40
                height: 40
                anchors.centerIn: parent
                color: mouseArea.containsMouse ? "white" : "grey"
                visible: model.index == view.currentIndex

                MouseArea {
                    id: mouseArea

                    anchors.fill: parent
                    hoverEnabled: true

                    onClicked: view.model.move(view.currentIndex, view.currentIndex+1, 1)
                }
            }
        }

        model: ListModel {
            ListElement { number: 1 }
            ListElement { number: 2 }
            ListElement { number: 3 }
            ListElement { number: 4 }
        }

        move: Transition {
            NumberAnimation { properties: "x"; duration: 200 }
        }

        moveDisplaced: Transition {
            NumberAnimation { properties: "x"; duration: 200 }
        }
    }
}

如果您要运行此应用程序,您将看到以下显示:

应用启动截图

将光标移动到灰色框的左下部分会将框颜色更改为白色,如下所示:

将鼠标悬停在第一个框上

单击按钮的那一刻,将触发动画以交换ListView的第一个和第二个元素。不幸的是,完成后,您可能得到以下结果:

点击框的结果

根据代码行color: mouseArea.containsMouse ? "white" : "grey",我预计矩形是灰色的,因为鼠标不再包含在MouseArea中。

所以我的问题是:

  1. 我的代码有问题吗
  2. 这是一个错误吗
  3. 可以做些什么来纠正这种行为
  4. 也许可以解释为什么会发生这种情况

标签: qtqmlqt5

解决方案


问题是指令:

visible: model.index == view.currentIndex

当元素移动时,该指令在 True 和 False 之间变化,因此它在转换中被认为是不稳定的,这就是它产生这种未定义行为的原因。ListView提供了一个稳定的属性,称为ListView.isCurrentItem指示当前项目。

解决方案是下一个:

delegate: Rectangle {
    id: rect // <--- set id
    width: 100
    height: 200
    color: "black"
    radius: 10

    Rectangle {
        width: 40
        height: 40
        anchors.centerIn: parent
        color: mouseArea.containsMouse ? "white" : "grey"
        visible: rect.ListView.isCurrentItem // <--- change this line
        MouseArea {
            id: mouseArea

            anchors.fill: parent
            hoverEnabled: true

            onClicked: view.model.move(view.currentIndex, view.currentIndex+1, 1)
        }
    }
}

推荐阅读