How to host dynamic content in a QML component

I'm having trouble creating extensible components in QML. There are methods that work, but what I would like to do is something like this:

//Outline.qml
Rectangle {
  color: 'red'
  //Children are inserted here
}

//main.qml
Rectangle {
  ... 
  Outline {
    Text { I'm trying to inject this into the Outline component
      text: "Hi I'm the inner text!"
    }
  }
}

I know that I can achieve this by using the component Loaderand setting the instance sourceComponentto Component, but when I do something moderately complex (for example, to reuse dialogs), my ability to write functions and reference an instance of a child component is difficult. If the component was created in a single QML file, the id / function relationship would be great, and I could just refer directly to my text fields.

Here is an example bootloader:

//Outline.qml
Rectangle {
  id : root
  color: 'red'
  property Component content;
  Loader {
    source : root.content
  }
}

//main.qml
Rectangle {
  function getData(){
     return inner.getData(); 
     //ERROR inner is undefined because it is created by the Loader instance.
  }
  ... 
  Outline {
    content: Component {
        TextField {
          id: inner
          function getData(){
            return inner.text || 'none';
          }
        }
    }
  }
}

, . , , , . "" .

: QML, . : ReferenceError: getMe is not defined

import QtQuick 2.2
import QtQuick.Controls 1.0
import QtQuick.Layouts 1.1

Item {
    id: app
    width: 640
    height: 480

    function accessData(){
        output.text = getMe.text
    }

    Loader {
        width: parent.width
        height: 300
        sourceComponent: Component {
            Rectangle {
                anchors.fill: parent
                color: 'yellow'

                TextField {
                    anchors.centerIn: parent
                    id: getMe
                    placeholderText: 'Input data...'
                }
            }
        }
    }


    Button {
        id: button
        y: app.height - 50
        text: 'get data'
        onClicked: {
            accessData();
        }
    }

    Text {
        y: app.height - button.height
        id: output
        text: 'none'
    }
}

, "loader", sourceComponent ( ).

+3
1

,

  • ex: " id: yourLoader" ex: " id: yourRect"

  • , TextField.text

    Loader { id: yourLoader
             width: parent.width
             height: 300
             sourceComponent: Component {
    
         Rectangle {
                     property string yourText : getMe.text
                     id: yourRect
                     anchors.fill: parent
                     color: 'yellow'
    
            TextField {
                anchors.centerIn: parent
                id: getMe
                placeholderText: 'Input data...'
            }
        }
      }
    }
    
  • accessData​​p >

     function accessData(){
                    var rect= yourLoader.item //we get yourRect from the loader 
                     output.text = rect.yourText // yourText <-- getMe.text
    
     } 
    
+2

All Articles