前言

刚接触 QML 语言的时候,感觉很新鲜,上手及其简单,但是用着用着才发现在 QML 中创建静态的组件很简单,但是动
态组件应该怎么创建呢?

知识点

  • Loader

  • QML信号和槽机制

  • Qt.createQmlObject

  • Qt.createComponent
  • 效果展示

    目录

  • 目标需求说明

  • Loader 组件

  • Qt.createQmlObject()

  • Qt.createComponent()

  • 示例代码下载
  • 目标需求说明
    /**
    *   测试 QML 动态创建组件程序实例
    *
    *   需求
    *   1. 可以通过人机交互的方式动态创建测试子窗口
    *   2. 可以通过人机交互的方式动态删除最后一个测试子窗口实例对象
    *   3. 可以通过人机交互的方式动态改变并复原测试子窗口实例对象的风格
    */
    
    Loader 组件

    刚开始的时候,在网上查找的资料里面是用 Loader 来实现动态创建组件,它的 Demo 类似于浏览器,但是它的每一行是
    可以删除的,它是使用 QML 的绑定机制实现的动态效果,Loader 只是延时加载了类似浏览器的组件而已, 导致我误以为
    QML中的动态创建组件是通过 Loader 实现的,走了不少弯路,搞心态,最后都怀疑自己是不是理解能力有问题...

    Loader 在QML中不是用来动态创建组件的,它只是延时创建组件而已,且一个 Loader 对应一个组件,不能一对多的情况,
    Loader 是通过 source 属性来指定加载哪一个组件,同时也可以通过 sourceComponent 属性来延时加载自定义组
    件

    Qt.createQmlObject()

    引用自 Qt Help
    object createQmlObject(string qml, object parent, string filepath)

    返回从给定的qml字符串创建的新对象,该字符串将具有指定的父对象,如果创建对象时出错,则返回 null
    如果指定了filepath,则它将用于所创建对象的错误报告

    这个方法能实现我们想要的目标效果,在程序运行后动态的创建、删除 QML 组件,只是参数有点多,emm~~ 一下枚举出
    Qt.createQmlObject() 的使用方法吧

        var var_arg01 = String('import QtQuick 2.0; Rectangle {color: "%1"; width: 640; height: 50; y: %2 * 50}').arg(widgetSize % 2? "red": "blue").arg(widgetSize)
        var newObject = Qt.createQmlObject(var_arg01,
                                            id_rootWindow,
                                            "");
    

    可以看到创建一个 Rectangle 组件就需要写这么多代码,非常的麻烦,而且我尝试这使用 Qt.createQmlObject()
    创建自定义组件,各种报错,但是外部导入的模块就不会有那么多的曲折,目前我把这个接口定义为创建外部扩展模块的组
    件方法

    好的,既然有不爽,就有爽的方法,安排

    Qt.createComponent()

    引用自 Qt Help
    object createComponent(url, mode, parent)

    返回使用QML文件在指定的url处创建的组件对象,如果给定空字符串,则返回null。

    返回的组件的 component::status 属性指示组件是否已成功创建。如果状态是组件。
    有关错误说明,请参见 Component::errorString()。

    如果可选模式参数设置为组件。异步,组件将加载到后台线程中。Component::status 属性将是组件。加载在装货的时
    候。状态将更改为组件。
    准备好了吗如果组件加载成功,或组件。错误如果加载失败。此参数默认为组件.首选同步如果省略。

    如果模式设置为组件.首选同步,Qt将尝试同步加载组件,但可能会在必要时异步加载。可能导致异步加载的情况包括但不
    限于以下情况:

    URL引用网络资源

    由于正在异步加载另一个组件,因此正在创建该组件

    如果给定了可选的parent参数,它应该引用将成为所创建组件对象的父对象的对象。如果没有传递任何模式,这可以是第二
    个参数。

    呼叫组件.createObject在返回的组件上创建该组件的对象实例。

    这个方法能更好的实现我们想要的效果,因为在实际中我们需要动态创建的组件一般都是自定义封装的,当然视情况而定,
    程序是死的,人是活的嘛,反正 Qt 给我们提供了 Qt.createQmlObject() 和 object createComponent() 方法

    示例代码下载

    代码下载请跳转到github,详情见 dynamicMakeAssembly2

    posted on 2020-12-20 23:23  怪小子  阅读(2099)  评论(0)    收藏  举报