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. )
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
}
}