QtQuick Grid,鼠标事件不会传播到相邻的鼠标区域

QtQuick Grid, mouse events no propagating over adjacent mouse areas

我编写了这个简单的 qml 应用程序,它允许在网格上绘制像素:

import QtQuick 2.12
import QtQuick.Window 2.12

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Grid {
        id: grid
        anchors.fill: parent
        rows: 32
        columns: 64

        Repeater {
            model: grid.columns * grid.rows;
            delegate: delegateGridImage
        }
    }

    Component {
        id: delegateGridImage

        Item {
            id: gridItem
            property int currentColumn: index % grid.columns
            property int currentRow: Math.floor(index / grid.rows);

            // Resize to screen size
            width: grid.width / grid.columns
            height: grid.height / grid.rows

            Rectangle {
                id: pixel
                anchors.fill: parent
                property bool pixel_state: true
                color: if (pixel_state == true ) { "white" } else { "black" }

                MouseArea {
                    anchors.fill: parent
                    hoverEnabled: true
                    propagateComposedEvents: true
                    acceptedButtons: Qt.LeftButton | Qt.RightButton
                    onEntered: console.log(index)
                    onPressed: pixel.pixel_state ^= true

                }

            }
        }
    }
}

这很好用:

我希望能够通过单击鼠标来绘制多个像素。

我试过 onEntered 事件,但它只监听活动的鼠标区域,直到释放单击按钮。有没有办法不阻止其他鼠标区域的事件?

您可以使用全局MouseArea并通过GridchildAt(...)减去光标下方的当前项目。

Window {
    ... // remove the MouseArea of pixel

    MouseArea {
        anchors.fill: parent
        hoverEnabled: true
        acceptedButtons: Qt.LeftButton | Qt.RightButton

        property bool pixel_activate: true

        onPressed: {
            var child = grid.childAt(mouse.x, mouse.y)
            child.pixel_state ^= true
            pixel_activate = child.pixel_state
        }

        onPositionChanged: {
            if (!pressed) return;
            var child = grid.childAt(mouse.x, mouse.y)
            child.pixel_state = pixel_activate
        }
    }
}

您只需决定在按住按钮后要执行的操作(目前它执行第一个操作 activate/deactivate 和所有后续操作)。另请查看 MouseEvent passed by the signals pressedpositionChanged 以便区分按下的键。

Lasall 的解决方案非常有效。这是最终结果:

import QtQuick 2.12
import QtQuick.Window 2.12

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Grid {
        id: grid
        anchors.fill: parent
        rows: 32
        columns: 64

        Repeater {
            model: grid.columns * grid.rows;
            delegate: delegateGridImage
        }
    }

    Component {
        id: delegateGridImage

        Item {
            id: gridItem
            property int currentColumn: index % grid.columns
            property int currentRow: Math.floor(index / grid.rows);

            property bool pixel_state: false

            // Resize to screen size
            width: grid.width / grid.columns
            height: grid.height / grid.rows

            Rectangle {
                id: pixel
                anchors.fill: parent

                color: if (gridItem.pixel_state == true ) { "white" } else { "black" }
            }

        }
    }

    MouseArea {
        anchors.fill: parent
        hoverEnabled: true
        acceptedButtons: Qt.LeftButton | Qt.RightButton

        property bool pixel_activate: true

        onPressed: {
            var child = grid.childAt(mouse.x, mouse.y)
            child.pixel_state ^= true
            pixel_activate = child.pixel_state
        }

        onPositionChanged: {
            if (!pressed) return;
            var child = grid.childAt(mouse.x, mouse.y)
            child.pixel_state = pixel_activate
        }
    }
}