2017-03-17 36 views
1

我有一个代表附加到我的TableViewColumn,其中包含MouseArea。我使用MouseArea来检测表格中单个单元格的双击,这允许我显示一个TextField用于编辑目的。如何正确处理鼠标区域重叠的QML TableView中的鼠标事件?

问题是代表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鼠标)

在处理该信号,用鼠标参数的接受属性来控制这个鼠标区域是否处理媒体和所有未来的鼠标事件直到发布。默认是接受该事件,并且不允许其中的其他MouseAreas处理该事件。 如果接受设置为false,则在下一个按钮被按下之前,不会再有事件发送到此MouseArea。

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

+0

'MouseAreas'在哪里重叠,你想为每个行为做什么? – derM

+0

对不起,我编辑了我的答案,包括更多的细节。请看第二段。 – woggy

+0

所以你想要存档的唯一东西是选择行? – derM

回答

1

如果它只是在选择你想才达到你可以手动设置的选择:

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 
    } 
} 
+0

我希望我不必重新实现TableView选择逻辑。我想我可以将'MouseArea'的'pressed'信号连接到'TableView'手动传播信号,但不幸的是'pressed'也是一个属性的名称(导致错误)。 – woggy

+0

* duh *这个映射非常简单。我试图用'childAt(x,y)'来做,但从来没有找到合适的孩子。但如果我已经拥有它,那是在公园散步:-) – derM