如何在具有重叠鼠标区域的QML TableView中正确处理鼠标事件?

时间:2017-03-17 05:27:52

标签: qt pyqt qml mouseevent

我的TableViewColumn附有一位代表,其中包含MouseArea。我使用MouseArea检测表格中单个单元格的双击,这样我就可以显示TextField进行编辑。

问题是委托MouseArea阻止鼠标事件传播到TableView。这意味着TableView的选择行为不再有效。具体来说,我启用了SelectionMode.ExtendedSelection

MouseArea子项很简单,最初看起来像这样:

MouseArea{
    id: mousearea
    anchors.fill: parent
    onDoubleClicked: {
        showTextField()
    }
}

在查阅文档后,看起来应该可行:

MouseArea{
    id: mousearea
    anchors.fill: parent
    propagateComposedEvents: true        // new
    onDoubleClicked: {
        showTextField()
    }
    onPressed: mouse.accepted = false    // new
}

它的作用,除了现在我不能再拿起双击事件了(在MouseArea中)!这有意义,正如后面文档中所述:

  

按下(MouseEvent鼠标)

     

处理此信号时,使用mouse参数的accepted属性来控制此MouseArea是否处理按下以及所有将来的鼠标事件,直到发布。默认设置是接受事件,不允许此事件下的其他MouseAreas处理事件。 如果接受设置为false,则在下次按下该按钮之前,不会向此MouseArea发送更多事件。

似乎没有办法在TableView级别捕获单个细胞的鼠标事件。这是我第一天玩QML,所以我可能错过了一些明显的东西,但我的选择是什么?注意我正在使用PyQt。

1 个答案:

答案 0 :(得分:3)

如果只想要选择,您可以手动设置选择:

TableView {
    id: tv
    itemDelegate: Item {
        Text {
            anchors.centerIn: parent
            color: styleData.textColor
            elide: styleData.elideMode
            text: styleData.value
        }
        MouseArea {
            id: ma
            anchors.fill: parent
            onPressed: {
                tv.currentRow = styleData.row
                tv.selection.select(styleData.row) // <-- select here.
            }
            onClicked: {
                console.log(styleData.value)
            }
        }
    }

    TableViewColumn {
        role: 'c1'
        title: 'hey'
        width: 100
    }
    TableViewColumn {
        role: 'c2'
        title: 'tschau'
        width: 100
    }
    model: lm
}

现在我只选择。但是你可以编写自己的选择/取消选择 -logic。

您也可以从TableView.__mouseArea映射到代理。

import QtQuick 2.7
import QtQuick.Controls 1.4

ApplicationWindow {
    id: appWindow
    width: 1024
    height: 800
    visible: true

    ListModel {
        id: lm
        ListElement { c1: 'hallo1'; c2: 'bye' }
        ListElement { c1: 'hallo2'; c2: 'bye' }
        ListElement { c1: 'hallo3'; c2: 'bye' }
        ListElement { c1: 'hallo4'; c2: 'bye' }
        ListElement { c1: 'hallo5'; c2: 'bye' }
        ListElement { c1: 'hallo6'; c2: 'bye' }
        ListElement { c1: 'hallo7'; c2: 'bye' }
        ListElement { c1: 'hallo8'; c2: 'bye' }
        ListElement { c1: 'hallo9'; c2: 'bye' }
    }

    TableView {
        id: tv
        itemDelegate: Item {
            id: mydelegate
            signal doubleclicked()
            onDoubleclicked: console.log(styleData.value)
            Text {
                anchors.centerIn: parent
                color: styleData.textColor
                elide: styleData.elideMode
                text: styleData.value
            }

            Connections {
                target: tv.__mouseArea
                onDoubleClicked: {
                    // Map to the clickposition to the delegate
                    var pos = mydelegate.mapFromItem(tv.__mouseArea, mouse.x, mouse.y)
                    // Check whether the click was within the delegate
                    if (mydelegate.contains(pos)) mydelegate.doubleclicked()
                }
            }
        }

        TableViewColumn {
            role: 'c1'
            title: 'hey'
            width: 100
        }
        TableViewColumn {
            role: 'c2'
            title: 'tschau'
            width: 100
        }
        model: lm
    }
}