簡體   English   中英

model 和委托的自定義視圖都可以從 QML 文件訪問

[英]Custom view with model and delegate both accessible from both QML files

雖然我已經想通了,但還是花了很長時間。 如果您知道一個不那么復雜的解決方案 - 請分享。

我想提供一個自定義View ,它適用於任何類型的model (帶有任意命名的字段):

  • model: 3
  • model: [ "red", "yellow", "green" ]
  • model: [ {color: "red"}, {color: "yellow"}, {color: "green"} ]
  • model: ListModel{ ListElement{color: "red"}; ListElement{color: "green"} }
  • 子類QAbstractItemModel等...

為此,我決定提供一個property Component delegate ,用戶將使用將插入到我的View深處的可視Item來填充該屬性。

但是, View還需要從同一個delegate訪問一些信息,否則它會促進不必要的代碼重復,或者代理model的不必要的復雜性。

MyView {
     mymodel: ["red", "blue"]
     mydelegate: Text {
         text: "color=" + modelData.name
         must_also_somehow_set_color_of_MyView_element_to: modelData.color
     }
}

...其中 MyView 應該是這樣的:

Column {
    Repeater {
        model: mymodel
        delegate: Rectangle {
            color: somehow_get_color_from_mydelegate
            Text {} // <--- instantiate mydelegate here with data from mymodel
        }
    }
}

這樣做似乎很容易,但幼稚的嘗試並沒有奏效。 作為答案發布的解決方案對我有用。

訣竅是modelRepeaterInstantiatordelegate可見,它包含對所述delegate可見的所有內容,包括indexmodelData

所述model可用作ListModel.append()的參數以創建具有單個元素的ListModel

It can then be assigned as a model to a Repeater which will load the delegate with a copy of all context properties that QML normally derives from the element of View 's model including index , modelData and model itself.

實例化后, Repeater / Instantiator觸發onItemAdded / onObjectAdded信號,該信號可用作獲取對View delegate實例的引用的提示

可以要求View的用戶在delegate中提供一個根property ,該屬性將存儲View可以使用的獲得/計算的值

或者, View可以包含另一個RepeaterInstantiator器,並請求另一個delegate來獲取它自己需要的值。 或者一個容器類型可以封裝View的數據和可視的Item

例子:

MyView.qml

import QtQuick 2.0
import QtQml.Models 2.1
Column {
    property var mymodel
    property Component mydelegate

    Repeater {
        model: mymodel
        delegate: Rectangle {
            width: childrenRect.width; height: childrenRect.height

            //color: model.color //works if "mymodel" has role "color"
            property var myitem: null //this will hold instance of mydelegate
            color: ( null !== myitem
                     && undefined !== myitem.bgcolor ) 
                     ? myitem.bgcolor : "transparent" //reads property of mydelegate

            // <-- mydelegate will be injected here
            Repeater {
                delegate: mydelegate
                model: ListModel{
                    Component.onCompleted: append(model)
                }
                onItemAdded: myitem = item
                onItemRemoved: myitem = null
            }
        }
    }
}

UsageExamples.qml

import QtQuick 2.0
import QtQuick.Window 2.0
Window{
    visible: true
    Row {
        spacing: 10

        MyView {
            mymodel: ListModel {
                ListElement{ name: "roses"; color: "red";   }
                ListElement{ name: "violets"; color: "blue";   }
            }
             mydelegate: Text {
                 text: name
                 property color bgcolor: model.color
             }
        }

        MyView {
             mymodel: [{name: "roses", color: "red"}, {name: "violets", color: "blue"}]
             mydelegate: Text {
                 text: modelData.name
                 property color bgcolor: modelData.color
             }
        }

        MyView {
             mymodel: ["red", "blue"]
             mydelegate: Text {
                 text: "color="+modelData
                 property color bgcolor: modelData
             }
        }

    }
}

我認為你真的在尋找一個加載器來實例化委托,而不是第二個中繼器。 您還可以通過使用別名來簡化一點。 嘗試這樣的事情:

Column {
    property alias mymodel: repeater.model
    property alias mydelegate: loader.sourceComponent

    Repeater {
        id: repeater
        delegate: Rectangle {
            width: childrenRect.width; height: childrenRect.height

            color: ( null !== loader.item
                     && undefined !== loader.item.bgcolor ) 
                     ? loader.item.bgcolor : "transparent"

            Loader {
                id: loader
            }
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM