2017-05-15 31 views
0

在我的QML項目中,我需要一個對象來捕獲其子對象的所有UI事件。所以,如果它的任何一個孩子註冊了一個點擊或其他東西,父對象需要知道它。這裏的問題是所有的子對象都是預定義的類,如MyButton或MyComboBox。這些類都定義了不能被覆蓋的MouseAreas和onClicked()函數。因此,我需要父對象捕獲其子項的所有事件,而不修改子項的MouseAreas。請讓我知道完成此操作的最佳方法。QML - 捕獲子對象的所有UI事件

+0

你需要知道**哪個**'MouseArea'被點擊了嗎? – derM

回答

2

您可以抓取對象樹,將函數連接到每個onClicked -signal。

爲此,我們需要三個部分組成:

  • 即應連接
  • ,做一個創建另外一個函數來調用自定義參數的信號爬行
  • 的函數功能的信號。

我選擇,我的信號應得的參數:senderarguments。發件人是我點擊的對象,並且arguments是點擊對象的clicked-信號的參數。對於QtQuick.Controls 2.x Button s這是空的,並且對於MouseArea s包含一個條目(mouse)。

signal somethingWasClicked(var sender, var arguments) 

由於這個信號還沒有爲每個點擊的對象相同的簽名clicked,我們不能直接將其連接到這個信號。我們需要一箇中介函數來調用我們的信號,在它的範圍內有必要的參數並且沒有參數。我們需要爲每個我們窺視的對象動態構建它。

function createSpyFunction(object) { 
    return function() { somethingWasClicked(object, arguments) } 
} 

而且最後的抓取功能。我們需要存儲我們在某處創建的函數。爲此,我利用所有QtObject在某種意義上都是JS對象的事實,所以我可以使用Object.definePropertyto dynamically add JS-properties給他們。在這裏,我可以存儲我們的功能,而不需要對他們自己的組件的源代碼進行編程。 創建此功能後,我connect它到onClicked處理程序。

function crawlChildren(obj) { 
    if (obj.onClicked) { 
     Object.defineProperty(obj, '__clickedFunction', { value: createSpyFunction(obj) }) 
     obj.onClicked.connect(obj.__clickedFunction) 
    } 
    if (obj.children) { 
     var i = 0 
     for (; i < obj.children.length; i++) { 
      crawlChildren(obj.children[i]) 
     } 
    } 
} 

這個功能我終於在

Component.onCompleted: crawlObj(this.contentItem) 
我PROGRAMM根 ApplicationWindow

調用。


正如我只把它在Component.onCompleted -handler,將在此之後被添加的對象,不會被窺探uppon。要改變這一點,我們還需要監視onChildrenChanged,並抓取新添加的對象。這個過程幾乎是相似的,所以這是留給用戶的一個練習,或者可能會遇到一個新的問題。

+0

是這樣做的。謝謝! – user1765354

0

您可以嘗試用MouseArea覆蓋您的物品。在事件處理程序中,您可以檢查位置並調用基礎項目的事件處理程序。

Item { 
    MyButton { id: mybutton 
     /* set the anchors */ 
    } 
    MyMouseComboBox { id: myMouseComboBox 
    /* set the anchors */ 
    } 

    MouseArea { 
    anchros.fill: parent 
    onClicked: { 
     // mouse.accepted = false 
     // Check whether clicked point is within mybutton 
     // on true, call mybutton.doSomething() 
     // or call mybotton.onPressed(mouse) 
    } 
} 
+0

然後,你不能處理任何其他'MouseArea'的'onPressed'處理程序 – derM

+0

否。可以通過調用'mybutton.onPressed(mouse)' –

+0

來調用處理程序是的,所以你需要通過對象樹找到你的方式來找到所有'MouseArea',其圖層是未知的。 – derM