• QML动态创建自定义组件


    一、动态加载和实例化对象:createComponent

    例子1:

    ①、创建本地的QML文件,注意文件第一个字母要大写

    ZStation.qml

    import QtQuick 2.5
    
    Rectangle{
        property string mName: "station"
        signal entered(string objName);
        signal exited();
        property int station_ width/3
    
        id: root
        color: Qt.rgba(0,0,0,0)
         90
        height: width/3
        Rectangle{
            id: station
            color:"green"
             station_width
            height: width
            radius: width/2
        }
        Text {
            anchors.top:parent.top;
            anchors.left: station.right;
            anchors.leftMargin: 5;
             30
            height: 12
            text: mName
            color: "white"
        }
        MouseArea {
            hoverEnabled: true;
            anchors.fill: parent;
            onEntered: {
                root.entered(root.objectName);
            }
            onExited: {
                root.exited();
            }
        }
    }

    ②、在主qml里动态创建并连接信号槽

    function addStation(x, y, id, name){
        console.log(x,y,id,name);
        var componentIn = Qt.createComponent("ZStation.qml");
        if (componentIn.status === Component.Ready) {
            var objIn = componentIn.createObject(root, {"mName":name, "objectName":id});
            if(auto_scale){
                x = getNearX(x);
                y = getNearY(y);
            }
    
            objIn.x = x;
            objIn.y = y;
            objIn.entered.connect(root.showPopInfo)
            objIn.exited.connect(root.hidePopInfo)
            station_list.push(objIn);
            console.log(x,y);
        }else{
            console.log("qml create station err:",componentIn.errorString());
        }
    }

    例子2:

    ①、main.qml

    import QtQuick 2.9
    import QtQuick.Window 2.2
    
    Window {
        id: mainWin
        visible: true
         640
        height: 480
        title: qsTr("Hello World")
    
        LoginPage {
             300
            height: 200
            anchors.centerIn: parent
        }
    }

    ②、LoginPage.qml

    import QtQuick 2.0
    import QtQuick.Controls 2.3
    
    Rectangle {
        id: loginPage
         400
        height: 300
        color: "#051f58"
        radius: 8
        clip:true
    
        Button {
            text: "登录页面-登录按钮"
            anchors.centerIn: parent
            onClicked: {
                // 隐藏登录页面
                loginPage.visible = false // 不能销毁,否则下面的"主页面"也会跟随销毁,则后面
                // 点击"主页面-关闭按钮",将无法销毁关闭"主页面"
    
                // 在主窗口(mainWin)上显示主页面
                var compMainPage = Qt.createComponent("MainPage.qml")
                .createObject(mainWin, {x:50, y:50, 200, height:250});
            }
        }
    }

    ③、MainPage.qml

    import QtQuick 2.0
    import QtQuick.Controls 2.3
    
    Rectangle {
        id: mainPage
        color: "#498ff8"
        radius: 8
    
        Button {
            text: "主页面-关闭按钮"
            anchors.centerIn: parent
            onClicked: {
                // 销毁关闭主页面
                mainPage.destroy()
            }
        }
    }

    参考:https://www.cnblogs.com/linuxAndMcu/p/13566502.html

    PS: 

    ①、createComponent的返回值

     ②、创建过程时间是不确定的,我们上面的例子都是直接创建并判断状态,大多数情况是没问题,但是遇到特殊情况如:加载多种依赖或位于缓慢服务器中的QML时,会很慢【而且貌似创建函数不会阻塞】,故正确做法是:加一个判断

    function createImageObject() {
        component = Qt.createComponent("dynamic-image.qml");
        if (component.status === Component.Ready || component.status === Component.Error) {
            finishCreation();
        } else {
            component.statusChanged.connect(finishCreation);
        }
    }
    
    function finishCreation() {
        if (component.status === Component.Ready) {
            var image = component.createObject(root, {"x": 100, "y": 100});
            if (image === null) {
                console.log("Error creating image");
            }
        } else if (component.status === Component.Error) {
            console.log("Error loading component:", component.errorString());
        }
    }

    例子位于QMLBook的第15章节,动态创建组件。

    ③、销毁

    item=Qt.createQmlObject(...);
    ... item.destroy();

    二、动态创建Component

    这个方式和上面原理一致,component1是事先定义好的Component

     Component.onCompleted: {
            var obj1 = component1.createObject(root, { "color": "red", "width": 100, "height": 100})
            var obj2 = component2.createObject(root, { "color": "green", "width": 200, "height": 200})
            var obj3 = component3.createObject(root, { "color": "gray", "width": 300, "height": 300})
        }

    三、从文本文件动态实例化:createQmlObject

    1、接口

     qml:qml文本

     parent:对象的父亲

     filepath:存储创建对象时的错误报告

     返回:立即返回创建的对象或null,这是与上面其他接口不一样的:

    2、例子1:

    import QtQuick 2.5
    
    Item {
        id: root
    
         1024
        height: 600
    
        function createItem() {
            Qt.createQmlObject("import QtQuick 2.5; Rectangle { x: 100; y: 100;  100; height: 100; color: \"blue\" }", root, "dynamicItem");
        }
    
        Component.onCompleted: root.createItem();
    }

    四、createComponent

    createComponent其实和createObject一样,除了createComponent多了一个指定是否同步创建的参数,可以认为就是一个createObject,这里不加例子了

     如图,多了mode参数

  • 相关阅读:
    显示保存布局按钮OO ALV(set_table_for_first_display)
    ◆◆0ALV单元格颜色代码
    添加标准状态栏(status)
    添加自定义状态栏(GUI status)
    添加布局(layout)按钮
    添加页眉Top of page和页脚End of Page
    显示设定
    列属性设定-修改列标签名(label),自动优化显示宽度
    cs20_5-1
    cs20_4-2
  • 原文地址:https://www.cnblogs.com/judes/p/15603503.html
Copyright © 2020-2023  润新知