JavaScript中 创建动态 QML 对象的方法

一、动态创建对象

有两种方法可以从 JavaScript 动态创建对象:

  • 调用 Qt.createComponent() 动态创建 Component 对象
  • 使用 Qt.createQmlObject() 从 QML 字符串创建对象

虽然动态创建的对象可以与其他对象一样使用,但它们在 QML 中没有 id。

1.1、动态创建组件

可以调用它的 createObject() 方法来创建该组件的一个实例。这个函数可以接受两个参数:

第一个是新对象的父对象。父对象可以是图形对象(即 Item 类型)或非图形对象(即 QtObject 或 C++ QObject 类型)。只有带有图形父对象的图形对象才会被渲染到 Qt Quick 可视画布上。如果希望稍后设置父级,可以安全地将 null 传递给此函数。
第二个是可选的,是一个属性值对的映射,它定义了对象的初始任何属性值。此参数指定的属性值在对象创建完成之前应用于对象,避免在必须初始化特定属性以启用其他属性绑定时可能发生的绑定错误。此外,与在创建对象后定义属性值和绑定相比,性能优势很小。
示例。

Sprite.qml 它定义了一个简单的 QML 组件:

import QtQuick 2.0

Rectangle { width: 80; height: 50; color: "red" }

main.qml 导入了一个 componentCreation.js JavaScript 文件,该文件将创建 Sprite 对象:

import QtQuick 2.0
import "componentCreation.js" as MyScript

Rectangle
{
    id: appWindow
    width: 300; height: 300

    Component.onCompleted: MyScript.createSpriteObjects();
}

componentCreation.js

var component;
var sprite;

function createSpriteObjects()
{
    component = Qt.createComponent("Sprite.qml");
    if (component.status == Component.Ready)
        finishCreation();
    else
        component.statusChanged.connect(finishCreation);
}

function finishCreation()
{
    if (component.status == Component.Ready)
    {
        sprite = component.createObject(appWindow, {x: 100, y: 100});
        if (sprite == null)
        {
            console.log("Error creating object");
        }
    }
    else if (component.status == Component.Error)
    {
        console.log("Error loading component:", component.errorString());
    }
}

当使用带有相对路径的文件时,路径应该是相对于执行 Qt.createComponent() 的文件。

也可以通过 incubateObject() 函数在不阻塞的情况下实例化组件。

1.2、从 QML 字符串创建对象

可以使用 Qt.createQmlObject() 函数从 QML 字符串创建 QML 对象,如下例所示:

const newObject = Qt.createQmlObject(`
    import QtQuick 2.0
    Rectangle
    {
        color: "red"
        width: 20
        height: 20
    }
    `,
    parentItem,
    "myDynamicSnippet"
);
  • 第一个参数是要创建的 QML 字符串。
  • 第二个参数是新对象的父对象,适用于组件的父参数语义同样适用于 createQmlObject()
  • 第三个参数是与新对象关联的文件路径,这用于错误报告。

如果 QML 字符串使用相对路径导入文件,则路径应该相对于定义父对象(方法的第二个参数)的文件。

在构建静态 QML 应用程序时,会扫描 QML 文件以检测导入依赖项。这样,所有必要的插件和资源都会在编译时解决。但是,这仅考虑显式导入语句(位于 QML 文件顶部的语句),而不考虑包含在字符串文字中的导入语句。为了支持静态构建,用户需要确保使用 Qt.createQmlObject() 的 QML 文件在文件顶部明确包含所有(包括字符串文字内部)必要的导入。

二、动态删除对象

在许多用户界面中,将可视对象的不透明度设置为 0 或将可视对象移出屏幕而不是将其删除就足够了。 但是,如果有大量动态创建的对象,则删除未使用的对象可能会获得有价值的性能优势。

请注意:永远不应该手动删除由便利 QML 对象工厂(例如 Loader 和 Repeater)动态创建的对象。此外,应该避免删除不是自己动态创建的对象。

可以使用 destroy() 方法删除项目。 此方法有一个可选参数(默认为 0),用于指定销毁对象之前的近似延迟(以毫秒为单位)。

示例。application.qml 创建 SelfDestroyingRect.qml 组件的五个实例。 每个实例运行一个 NumberAnimation,当动画完成时,调用它的根对象上的 destroy() 来销毁自己:

application.qml   

import QtQuick 2.0

Item
{
    id: container
    width: 500; height: 100

    Component.onCompleted:
    {
        var component = Qt.createComponent("SelfDestroyingRect.qml");
        for (var i=0; i<5; i++)
        {
            var object = component.createObject(container);
            object.x = (object.width + 10) * i;
        }
    }
}

SelfDestroyingRect.qml

import QtQuick 2.0

Rectangle
{
    id: rect
    width: 80; height: 80
    color: "red"

    NumberAnimation on opacity
    {
        to: 0
        duration: 1000

        onRunningChanged:
        {
            if (!running)
            {
                console.log("Destroying...")
                rect.destroy();
            }
        }
    }
}

或者,application.qml 可以通过调用 object.destroy() 销毁创建的对象。

请注意:对该对象内的对象调用 destroy() 是安全的。 对象不会在调用 destroy() 的瞬间被销毁,而是在该脚本块结束和下一帧之间的某个时间被清除(除非指定了非零延迟)。

另请注意,如果 SelfDestroyingRect 实例是像这样静态创建的:

Item
{
    SelfDestroyingRect
    {
        // ...
    }
}

这会导致错误,因为对象只有在动态创建时才能动态销毁。

使用 Qt.createQmlObject() 创建的对象可以类似地使用 destroy() 销毁:

const newObject = Qt.createQmlObject(`
    import QtQuick 2.0
    Rectangle
    {
        color: "red"
        width: 20
        height: 20
    }
    `,
    parentItem,
    "myDynamicSnippet"
);
newObject.destroy(1000);

到此这篇关于 JavaScript中 创建动态 QML 对象的方法的文章就介绍到这了,更多相关 JavaScript 创建动态 QML 对象内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • QT QML的元素布局的实现

    本文介绍QT QML跨平台移动APP开发中的元素布局的相关问题,先看一张图,我们来分析一下其中的问题: 这张图片中,有如下问题: 整体的布局没有居中显示 班级名称: 没有和 请输入班级名称输入框垂直对齐 和输入框的距离太远 班主任的提示也一样 最后的Button一行,需求要求右对齐,在QML的程序中没有实现 代码修改完以后的效果: 改变宽度试一下: 原代码说明: main.qml import QtQuick 2.12 import QtQuick.Window 2.12 Window { vi

  • JavaScript中 创建动态 QML 对象的方法

    一.动态创建对象 有两种方法可以从 JavaScript 动态创建对象: 调用 Qt.createComponent() 动态创建 Component 对象 使用 Qt.createQmlObject() 从 QML 字符串创建对象 虽然动态创建的对象可以与其他对象一样使用,但它们在 QML 中没有 id. 1.1.动态创建组件 可以调用它的 createObject() 方法来创建该组件的一个实例.这个函数可以接受两个参数: 第一个是新对象的父对象.父对象可以是图形对象(即 Item 类型)或

  • javascript的document中的动态添加标签实现方法

    document的高级篇中提供了节点操作的函数,具体包括:获取节点,改变节点,删除节点,替换节点,创建节点,添加节点,克隆节点等函数.我们可以利用这些函数动态改变html的节点. 1.JavaScript <script type="text/javascript"> function test1(){//对个节点的ID相同时候的情况 var myhref = document.getElementById('same'); window.alert(myhref.inne

  • JavaScript创建防篡改对象的方法分析

    本文实例讲述了JavaScript创建防篡改对象的方法.分享给大家供大家参考,具体如下: 之前的 JavaScript,开发人员可能会意外修改了别人的代码,甚至重写原生对象!现在,在 ECMAScript 5 中可以定义防篡改对象啦O(∩_∩)O~ 不过,一旦把对象定义为防篡改之后,就无法撤销了哦. 1 不可扩展对象 默认情况下,所有的对象都是可扩展的,即可以随意地添加属性和方法.现在,使用 Object.preventExtensions(person) 方法后,对象就不可以扩展咯: <scr

  • 原生JavaScript创建不可变对象的方法简单示例

    本文实例讲述了原生JavaScript创建不可变对象的方法.分享给大家供大家参考,具体如下: Javascript是一种灵活的语言,你可以重新定义任何东西,但是当项目变得复杂时,我们会发现可变数据结构的问题.随着JavaScript的最新版本的发布这种情况发生了改变.现在可以创建不可变的对象了.本文介绍如何用三种不同的方法来做. 对象的不变性意味着我们不希望对象在创建后即以任何方式更改(将它们设置为只读类型). 假设我们需要定义一个 car 对象,并在整个项目中使用它的属性来执行操作.我们不能允

  • javascript创建动态表单的方法

    本文实例讲述了javascript创建动态表单的方法.分享给大家供大家参考.具体实现方法如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head>

  • javaScript中定义类或对象的五种方式总结

    第一种方式: 工厂方法 能创建并返回特定类型的对象的工厂函数(factory function). function createCar(sColor){ var oTempCar = new Object; oTempCar.color = sColor; oTempCar.showColor = function (){ alert(this.color); }; return oTempCar; } var oCar1 = createCar(); var oCar2 = createCa

  • JavaScript中5种调用函数的方法

    这篇文章详细的介绍了Javascript中各种函数调用的方法及其原理,对于理解JavaScript的函数有很大的帮助! JavaScript,调用函数的5种方法 一次又一次的,我发现,那些有bug的Javascript代码是由于没有真正理解Javascript函数是如何工作而导致的(顺便说一下,许多那样的代码是我写的).JavaScript拥有函数式编程的特性, 当我们选择面对它的时候,这将成为我们前进的阻碍. 作为初学者,我们来测试五种函数调用的方法,从表面来看我们会认为那些函数与C#中函数的

  • javascript中数组(Array)对象和字符串(String)对象的常用方法总结

    本文实例总结了javascript中数组(Array)对象和字符串(String)对象的常用方法.分享给大家供大家参考,具体如下: 综述:笔者经常将数组的方法和字符串的方法混淆,这里写篇日志,做个区分 1.字符串对象 String是JavaScript中的五种基本类型之一. (1)字符串对象的创建 例1: var str="Hello world"; 或者 var str=new String("Hello world") (2)charAt()方法 charAt(

  • JavaScript中windows.open()、windows.close()方法详解

    windows.open()方法详解: window.open(URL,name,features,replace)用于载入指定的URL到新的或已存在的窗口中,并返回代表新窗口的Window对象.它有4个可选的 参数: URL:一个可选的字符串,声明了要在新窗口中显示的文档的 URL.如果省略了这个参数,或者它的值是空字符串,那么新窗口就不会显示任何文档. name:一个可选的字符串,该字符串是一个由逗号分隔的特征列表,其中包括数字.字母和下划线,该字符声明了新窗口的名称.这个名称可以用作标记

  • Vue之Vue.set动态新增对象属性方法

    当我们给一个比如props中,或者data中被观测的对象添加一个新的属性的时候,不能直接添加,必须使用Vue.set方法 Vue.set方法用来新增对象的属性.如果要增加属性的对象是响应式的,那该方法可以确保属性被创建后也是响应式的,同时触发视图更新 这里本来food对象是没有count属性的,我们要给其添加count属性就必须使用Vue.set方法,而不能写成'this.food.count = 1' 以上这篇Vue之Vue.set动态新增对象属性方法就是小编分享给大家的全部内容了,希望能给大

随机推荐