2016-09-21 49 views
0

如何創建一些可重用的QML對象,它可以注入另一個對象?如何製作一些可重用的QML對象,它可以注入另一個QML對象?

我曾嘗試使用Component & Loader,但似乎不是我想要的。 (它仍然封裝整個QML類型和彈性的缺乏,難以重用)

用例:

Card.qml

import QtQuick 2.0 
import QtQuick.Layouts 1.3 

Rectangle { 
    default property var innerObject 
    property string titleText: "[Hello Untitled Title]" 
    id: root 
    color: "#fff" 
    ColumnLayout { 
     anchors.fill: parent 
     Rectangle { 
      id: header 
      height: 10 
      width: parent.width 
      color: "#666" 
      RowLayout { 
       Text { text: titleText; color: "#fff" } 
      } 
     } 

     // How to inject innerObject in here ? 

    } 
} 

main.qml

import QtQuick 2.0 
import QtQuick.Layouts 1.3 

Card { 
    titleText: "Image Information" 
    ColumnLayout { /* .......*/ } // innerObject 
} 

Card { 
    titleText: "Image Viewer" 
    Rectangle { /* .......*/ }  // innerObject 
} 
+3

的可能的複製[如何你是否將QML項目分配給QML中的組件屬性,然後在組件內部使用該對象?](http://stackoverflow.com/questions/5021350/how-do-you-assign-a-qml-item-to -a-component-property-in-qml-and-then-use-that-ob) –

+0

尤其見:http://stackoverflow.com/a/10031214/6845813 –

回答

1

答案我掛像這樣的作品:

Main.qml

Card { 
    titleText: "Image Viewer" 
    innerObject: Rectangle { 
     Component.onCompleted: { 
      console.log(parent.objectName) 
     } 
    } 
} 

Card.qml

Rectangle { 
    property string titleText: "[Hello Untitled Title]" 

    default property alias innerObject : innercolumn.children 


    id: root 
    color: "#fff" 
    ColumnLayout { 
     id: innercolumn 
     objectName: "column" 
     anchors.fill: parent 
     Rectangle { 
      id: header 
      height: 10 
      width: parent.width 
      color: "#666" 
      RowLayout { 
       Text { text: titleText; color: "#fff" } 
      } 
     } 
    } 
} 
+1

實際上,你根本不需要佔位符項目,你可以直接使用'默認屬性別名innerObject:innerColumn.children' – dtech

+0

嗯,是的,似乎工作。 –

+0

至於「默認屬性」在「本地」使用時不踢,它看起來像一個錯誤。這應該不重要。 – dtech

1

它是不是強制性的,你使用帶有組件的。你可以去:

Loader { 
    source: "Something.qml" 
} 

當源是什麼,可以加載同步,你可以直接使用像綁定的東西裝載機的item,無需擔心是否被創建它。如果通過網絡加載,則必須延遲綁定直到項目完成,並使用Binding元素或Qt.binding()分別以聲明式或命令式方式進行。

在你的情況下,一個加載器將是適當的,內部動態對象的屬性是一個Component。通過這種方式,您可以使用內聯組件或使用來自現有源的Qt.createComponent()進行填充。

property Component innerObject 
... 
innerObject: Component { stuff } 
... 
innerObject: Qt.CreateComponent(source) 

當然,還有更先進的方式來做到這一點,例如,「通用QML模型對象」我所闡述here。它允許以聲明方式和命令方式快速輕鬆地創建任意數據結構樹,並且由於對象也是模型,因此您可以直接使用帶有中繼器的列表視圖或定位器元素來排列gui,而無需每次都實際編寫UI代碼。

此外,從您的main.qml代碼示例 - qml文件中不能有多個根元素。

編輯:本default property方法確實有效,如果元素移動到它自己的QML文件,所以也基本上你可以只:

default property alias innerObject: innerColumn.children 

其中innerColumn是你ColumnLayout的ID。另外,innerObject可以是任何合法的名稱,因爲作爲默認屬性,它實際上不會被使用。

還有一個選項而不是使用默認屬性,當根項目仍然需要擁有自己的子項時仍然有用,但仍然有能力將聲明性對象重定向爲子對象的子項:

property alias content: innerColumn.children 
// and then 
content: [ Obj1{}, Obj2{}, Obj3{} ] // will become children of innerColumn 
+0

'卡{ titleText: 「圖像查看器」 數據:矩形{ Component.onCompleted:{ 的console.log(parent.objectName) } } } '如果在Card.qml中將內部對象名稱定義爲默認屬性別名data:inner_space.data,其中inner_space是'Item {id:inner_space; objectName:「inner」}'。 –

+0

其實讓我只顯示整個代碼。 –

+0

@TeemuRisikko - 如果它被移動到一個單獨的qml文件,它實際上是有效的。我從答案中刪除了該部分。 – dtech

2

我也想基於默認屬性和重排根來提出一個解決方案:

它可以嵌入另一個項目的項目:

MyItem.qml

import QtQuick 2.7 
import QtQuick.Layouts 1.2 

Rectangle { 
    id: root 
    default property Item contentItem: null 
    border { 
     width: 1 
     color: "#999" 
    } 
    ColumnLayout { 
     anchors.fill: parent 
     Rectangle { 
      Layout.fillWidth: true 
      height: 30 
      color: "lightgreen" 
     } 
     Item { 
      id: container 
      Layout.fillWidth: true 
      Layout.fillHeight: true 
     } 
    } 
    onContentItemChanged: { 
     if(root.contentItem !== null) 
      root.contentItem.parent = container; 
    } 
} 

可以如下使用:

main.qml

import QtQuick 2.7 
import QtQuick.Window 2.0 

Window { 
    visible: true 
    width: 600 
    height: 600 

    MyItem{ 
     width: 400 
     height: 400 
     anchors.centerIn: parent 
     Text { 
      text: "Hello!" 
      anchors.centerIn: parent 
     } 
    } 
} 

但我仍然@ddriver同意Loader是這種情況下,最好的解決辦法

相關問題