QML dynamically adds multiple buttons

If you want to lay out a large number of buttons in QML, if you write them one by one, it will be too low. The following introduces the use of Qt.createComponent to dynamically create components. Let’s take a look at the result graph (make sure your eyes are the right person. )

Insert picture description here

1. Introduction to createComponent() function

/*
 * 输入:
 *     url: 要创建组件的qml文件名称,例如 “TestButton.qml”
 *     mode: 设置当前创建的方式为同步还是异步(Component.Asynchronous(异步), Component.PreferSynchronous(优先同步))
 *     parent: 父对象
 * 输出:
 *     object:输出为创建后的组件对象
 */
object createComponent(url, mode, parent)

The first input parameter, url, is the qml file of the component to be created. Generally, it needs to be filled in; the
second parameter is whether the function is an asynchronous operation or a synchronous operation. If not set, the default is the second parameter Component.PreferSynchronous. In this mode, synchronization takes precedence, but there are special cases where asynchronous operations are performed:
1. The URL refers to network resources.
2. The component is created due to another component that is loaded asynchronously. The
third parameter is the parent object. You can leave it blank. Add the parent object by returning the createObject() of the object.
The return value is the component object. The status of the component has several states, as follows:

0:Component.Null  组件为空
1:Component.Ready 组件加载成功
2:Component.Loading 组件正在加载中
3:Component.Error 组件加载失败,可以调用component.errorString()查看错误信息

2. Introduction to createObject() function

This function creates and returns an object instance of this component, which will have the given parent and attributes. The properties parameter is optional. If the object creation fails, null is returned.

/*
 * 输入:
 *     parent: 父对象
 *     object properties: 组件中的属性设置,可选
 * 输出:
 *     object:输出为创建后的组件对象
 */
object createObject(parent, object properties)

The first input parameter is the parent object. If it is empty, the created component itself is the highest parent node. For example, to create a new independent window, the parent node should be set to null at this time, otherwise, the parent node in qml needs to be set To fill in the id.
The second parameter is the attribute in the component, for example, the corresponding id, width, height, etc. can be initialized when the instance is created.
The return value is an object. If the creation fails, the returned object is null at this time.

// 官方给出的例子,大家可以参考一下。
import QtQuick 2.0

  Item {
    
    
      id: container
      width: 300; height: 300

      function loadButton() {
    
    
          var component = Qt.createComponent("Button.qml");
          if (component.status == Component.Ready) {
    
    
              var button = component.createObject(container);
              button.color = "red";
          }
      }

      Component.onCompleted: loadButton()
  }

3. Code

MTButton.qml

/* MTButton.qml  组件qml文件 */

import QtQuick 2.0
import QtGraphicalEffects 1.0

Rectangle {
    
    
    property string showInfo: ""
    width: 100
    height: 100
    radius: 10
    visible: true
    color: "#004696"

    Text {
    
    
        id: info
        anchors.fill: parent
        horizontalAlignment: Text.AlignHCenter
        verticalAlignment: Text.AlignVCenter
        text: showInfo
        font.pointSize: 20
        color: "white"
    }

    layer.enabled: true
    layer.effect: DropShadow {
    
    
        transparentBorder: true
        color: "#004696"
        samples: 20
    }
}

main.qml

/* main.qml  主qml文件 */
import QtQuick 2.12
import QtQuick.Window 2.12

Window {
    
    
    id: root
    property int mainScreenWidth: 1080
    property int mainScreenHeight: 640
    visible: false
    width: mainScreenWidth - 15
    height: mainScreenHeight - 70
    title: qsTr("Hello World")
    flags: Qt.Tool
    color: "#c8c8c8"

    Component.onCompleted: {
    
    
        for(var i = 0; i < Qt.application.screens.length; ++ i) {
    
    
            mainScreenWidth = Qt.application.screens[i].width
            mainScreenHeight = Qt.application.screens[i].height
            visible = true
            break;
        }

        for( var i = 0; i < 84 ; i++) {
    
    
            createBtn(i);
        }
    }

    function createBtn(windowId) {
    
    
        var component = Qt.createComponent("MTButton.qml");
        if (component.status === Component.Ready) {
    
    
            var newWindow = component.createObject(root, {
    
    text:windowId + 1})
            var row = Math.floor(windowId /12)
            var col = windowId - row * 12
            newWindow.x = col * 150 + 70
            newWindow.y = row * 120 + 70
            newWindow.showInfo = windowId + 1
            return true
        }
        return false
    }

}

Guess you like

Origin blog.csdn.net/PRML_MAN/article/details/113554131