简体   繁体   中英

In QML, how can I create a parent Component that takes child Component instances and puts them in the parent Components hierarchy?

Qt's QML has a number of widgets where you instantiate the widget and then give it an instance of a Component for it to display and use.

For example, the Popup widget can be used like:

Popup { // <-- Parent Component
  Rectangle { // <-- Child Component
    width: 100;
    height: 100;
    color: 'red';
  }
}

How can I do this myself? How can I write a custom QML Component that will take a child Component instance and put it beneath my tree?

If I have a silly Component like:

// File Parent.qml
Rectangle {
  default property var child_inst;
  width: child_inst.width + 20;
  width: child_inst.width + 20;
  color:'red';
  child_inst;  // <-- how is this done?
}

and used like:

Parent {
  Text { text: 'hello world!' }
}

What is the syntax or mechanism by which I can instantiate or move the child_inst to be a child of my Parent ?

Wow, that's hella confusing way to put it, but if I understand correctly, you want to have children actually redirected to some other object automatically. This is possible, for example:

// Obj.qml
Rectangle {
  width: 50
  height: 50
  default property alias content: row.children
  Row {
    id: row
  }
}

and then:

  Obj {    
    Rectangle {
      width: 10
      height: 10
      color: "red"
    }
    Rectangle {
      width: 10
      height: 10
      color: "green"
    }
    Rectangle {
      width: 10
      height: 10
      color: "blue"
    }    
  }

The result is that the rgb rectangles are displayed in a row, because even though they are nested in Obj , they are internally delegated to the row.

Using a default property means that you don't have to specify it manually. Of course, if you don't want that, you can even use multiple different placeholders, for example, you can have:

  property alias content: contentItem.children // this is a column of contents
  property alias control: buttons.children // this is a row of buttons

Keep in mind that if you don't use the default property, you will have to specify the objects as a comma separated list in the case they are multiple:

  Obj {
    content : [
      Rectangle {
        width: 10
        height: 10
        color: "red"
      },
      Rectangle {
        width: 10
        height: 10
        color: "green"
      },
      Rectangle {
        width: 10
        height: 10
        color: "blue"
      }
    ]
  }

This is not necessary if it is a single object, it can be created like this:

  Obj {
    content : Rectangle {
      width: 10
      height: 10
      color: "green"
    }
  }

But you can also use a single target and have your row nest the objects externally, which can save you having to bother with the array notation and gives you more flexibility:

  Obj {
    content : Row {
      // bunch of stuff here
    }
  }

In this case, the content can be a simple positioned Item , that will serve as a placeholder, as it is the case for the popup component.

And finally, you can also use a Loader if you want to specify an inline component, that is one that is not defined in a dedicated QML file but using the Component element.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM