学习Component QML Type

组件是可重用的、封装的 QML 类型,具有定义明确的接口。

组件通常由组件文件(即 .qml 文件)定义。组件类型基本上允许 QML 组件在 QML 文档中内嵌定义,而不是作为单独的 QML 文件。这对于在一个 QML 文件中重复使用一个小组件,或定义一个在逻辑上属于文件中其他 QML 组件的组件可能很有用。

例如,这里有一个由多个装载机对象使用的组件。它只包含一个项目,即一个矩形:

import QtQuick 2.0

Item {
    width: 100; height: 100

    Component {
        id: redSquare

        Rectangle {
            color: "red"
            width: 10
            height: 10
        }
    }

    Loader { sourceComponent: redSquare }
    Loader { sourceComponent: redSquare; x: 20 }
}

结果:

请注意,虽然矩形本身会自动渲染和显示,但上述矩形并非如此,因为它是在组件中定义的。该组件封装了其中的 QML 类型,就像它们是在一个单独的 QML 文件中定义的一样,而且直到被请求(在本例中,被两个加载器对象请求)时才会被加载。因为 Component 不是从 Item 派生的,所以不能锚定任何东西。

定义 Component 与定义 QML 文档类似。一个 QML 文档有一个顶层项,它定义了该组件的行为和属性,而不能在该顶层项之外定义属性或行为。同样,一个组件的定义也包含一个顶层项(在上例中是一个矩形),除了一个 id(在上例中是 redSquare)外,不能在这个顶层项之外定义任何数据。

组件类型通常用于为视图提供图形组件。例如,ListView::delegate 属性需要一个组件来指定如何显示每个列表项。

也可以使用 Qt.createComponent() 动态创建组件对象。

创建上下文


组件的创建上下文与组件的声明上下文相对应。当该组件被 ListView 或 Loader 等对象实例化时,该上下文将被用作父上下文(创建上下文层次结构)。

在下面的示例中,comp1 是在 MyItem.qml 的根上下文中创建的,从该组件实例化的任何对象都可以访问该上下文中的 id 和属性,如 internalSettings.color。当 comp1 在其他上下文(如下面的 main.qml)中作为 ListView 委托使用时,它将继续访问其创建上下文中的属性(否则外部用户将无法访问这些属性)。

MyItem.qml

Item {
    property Component mycomponent: comp1

    QtObject {
        id: internalSettings
        property color color: "green"
    }

    Component {
        id: comp1
        Rectangle { color: internalSettings.color; width: 400; height: 50 }
    }
}

main.qml

ListView {
    width: 400; height: 400
    model: 5
    delegate: myItem.mycomponent    //will create green Rectangles

    MyItem { id: myItem }
}

创建上下文的生命周期必须长于任何已创建对象的生命周期。详情请参阅维护动态创建的对象。

属性

progress:real

加载组件的进度,从 0.0(未加载)到 1.0(已完成)。

status:enumeration

此属性显示组件加载的状态。状态可以是以下之一:

Component.Null 该组件没有可用数据
Component.Ready 该组件已加载,可用于创建实例。
Component.Loading 当前正在加载组件
Component.Error 加载组件时发生错误。调用 errorString() 将提供关于任何错误的可读描述。

url:url

信号

completed()

在对象实例化后发出。一旦建立了完整的 QML 环境,它就可以用来在启动时执行脚本代码。

onCompleted 信号处理程序可在任何对象上声明。处理程序的运行顺序未定义。

注:相应的处理程序是 onCompleted。

Rectangle {
    Component.onCompleted: console.log("Completed Running!")
    Rectangle {
        Component.onCompleted: console.log("Nested Completed Running!")
    }
}

destruction()

在对象开始销毁时发出。它可用于撤销响应 completed() 信号时已完成的工作,或应用程序中的其他命令代码。

onDestruction 信号处理程序可以在任何对象上声明。处理程序的运行顺序未定义。

注:相应的处理程序是 onDestruction。

方法

Qtobject createObject(QtObject parent,object properties)

QtObject createObject(QtObject 父对象,对象属性)

创建并返回该组件的对象实例,该实例将具有给定的父对象和属性。属性参数是可选的。如果对象创建失败,则返回 null。

对象将在与创建组件时相同的上下文中创建。当调用非 QML 创建的组件时,此函数将始终返回空值。

如果想创建对象而不设置父对象,可指定父对象值为 null。请注意,如果要显示返回的对象,您必须提供一个有效的父对象值或设置返回对象的父对象属性,否则该对象将不可见。

如果未向 createObject() 提供父对象,则必须保留返回对象的引用,以免垃圾回收器将其销毁。无论之后是否设置 Item::parent 都是如此,因为设置 Item 父对象并不会改变对象的所有权。改变的只是图形父对象。

从 QtQuick 1.1 开始,该方法接受一个可选的 properties 参数,该参数指定了创建对象的初始属性值映射。这些值将在对象创建最终完成前应用。这比在创建对象后设置属性值更有效,尤其是在定义了大量属性值集的情况下,而且还允许在创建对象前设置属性绑定(使用 Qt.binding)。

属性参数指定为属性值项的映射。例如,下面的代码创建了一个对象,其初始 x 值和 y 值分别为 100 和 100:

const component = Qt.createComponent("Button.qml");
if (component.status === Component.Ready) {
    component.createObject(parent, { x: 100, y: 100 });
}

动态创建的实例可以用 destroy() 方法删除。更多信息,请参阅从 JavaScript 动态创建 QML 对象。

string errorString()

返回对任何错误的可读描述。

字符串包括文件、位置和每个错误的描述。如果出现多个错误,则以换行符分隔。

如果没有错误,则返回空字符串。

object incubateObject(QtObject parent,object properties, enumeration mode)

为该组件实例创建一个孵化器。孵化器允许异步实例化新的组件实例,并且不会导致用户界面冻结。

父参数指定创建实例的父对象。省略该参数或传递空值将创建一个没有父对象的对象。在这种情况下,必须保留对创建对象的引用,以免垃圾回收器将其销毁。

属性参数被指定为属性值项的映射,这些值项将在创建对象时设置。模式可以是 Qt.Synchronous 或 Qt.Asynchronous,并控制实例是同步创建还是异步创建。默认为异步。在某些情况下,即使指定了 Qt.Synchronous,孵化器也可能以异步方式创建对象。如果调用 incubateObject() 的组件本身是异步创建的,就会出现这种情况。

所有三个参数都是可选的。

如果创建成功,该方法将返回一个孵化器,否则返回空。孵化器具有以下属性:

status - 孵化器的状态。有效值为 Component.Ready、Component.Loading 和 Component.Error。
object - 创建的对象实例。只有当孵化器处于就绪状态时才可用。
onStatusChanged - 指定状态改变时调用的回调函数。状态将作为参数传递给回调函数。
forceCompletion() - 调用以同步完成孵化。
下面的示例演示了如何使用孵化器:

const component = Qt.createComponent("Button.qml");

const incubator = component.incubateObject(parent, { x: 10, y: 10 });
if (incubator.status !== Component.Ready) {
    incubator.onStatusChanged = function(status) {
        if (status === Component.Ready) {
            print("Object", incubator.object, "is now ready!");
        }
    };
} else {
    print("Object", incubator.object, "is ready immediately!");
}

动态创建的实例可以用 destroy() 方法删除。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值