2017-03-17 68 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