封装一个QML组件定义。
import声明:import QtQml 2.15
实例化:QQmlComponet
属性
- progress: real
- status: enumeration
- url: url
连接的信号
- completed()
- destruction()
方法
- object createObject(QtObject parent, object properties)
- string errorString()
- object incubateObject(Item parent, object properties, enumeration mode)
详细说明
组件是可复用的,用定义清晰的接口封装QML类型。
组件通常由组件文件定义,就是.qml文件。组件类型本质上允许QML组件在QML document 中内联定义,而不是单独定义QML文件。这对于在QML文件中复用小组件,或者定义逻辑上属于其他QML组件的Component是非常有效的。
例如:下面是一个被多个加载器组件使用的Component,包含一个独立的Item,一个Rectangle 文件:
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 }
}
请注意,虽然Rectangle会自动渲染和显示,但是上面的Rectangle因为是在组件内定义的,所以不会自动刷新。组件将QML类型封装在其中,就像它们在单独的QML文件中定义一样,直到被请求时才加载(在本例中,由两个加载器对象加载)。因为Component不是从Item派生的,所以您不能将任何东西锚定到它。
定义组件类似于定义QML文档。QML文档有一个定义该组件的行为和属性的顶级项,并且不能定义该顶级项之外的属性或行为。同样,组件定义包含单个顶级项(在上面的示例中是一个矩形),并且不能定义该项之外的任何数据,除了id(在上面的示例中是redSquare)。
组件类型通常用于为视图提供图形化组件。例如,ListView::delegate属性需要一个组件来指定每个列表项如何显示。
组件对象也可以使用Qt.createComponent()动态创建。
创建情景
组件的创建上下文对应于声明组件的上下文。当组件被ListView或Loader这样的对象实例化时,这个上下文被用作父上下文(创建上下文层次结构)。
在下面的示例中,comp1是在MyItem的根上下文中创建的 .qml,并且从该组件实例化的任何对象都可以访问该上下文中的id和属性,例如internalSettings.color。当comp1在另一个上下文中用作ListView委托时(如main。qml),它将继续访问其创建上下文的属性(否则它将是外部用户私有的)。
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 }
}
创建上下文的生存期比任何创建的对象的生存期都要长,这一点很重要。有关更多细节,请参见
Maintaining Dynamically Created Objects.
文档属性
progress: real
- 加载组件的进度,从0到1
status: enumeration
组件加载状态,有如下状态:
- Component.Null - 组件没有可用数据
- Component.Ready - 组件已加载,可以创建实例
- Component.Loading - 组件加载中
- Component.Error - 组件加载中出现错误,调用 errorString() 取得可识别的错误信息
url: url
- 组件URL,用于构造组件的URL。
附加信号文档
completed()
对象实例化结束后被触发。一旦建立了完整的QML环境,就可以在启动时执行脚本代码。
onCompleted信号处理程序可以在任何对象上声明。处理程序的执行顺序是未定义的。
Rectangle {
Component.onCompleted: console.log("Completed Running!);
Rectangle {
Component.onCompleted: console.log("Nested Completed Running!")
}
}
注意: 对应的处理程序是 onCompleted
destruction()
对象摧毁时触发。可以用于撤销completed()信号的响应监听,或者执行应用程序中其他必要的代码。
onDestruction信号处理程序可以在任何对象上声明。处理程序的执行顺序未定义。
Rectangle {
Component.onDestruction: console.log("Destruction Beginning!")
Rectangle {
Component.onDestruction: console.log("Nested Destruction Beginning!")
}
}
注意: 对应的处理程序是 onDestruction
方法文档
object createObject(QtObject parent, object properties)
创建并返回该组件的对象实例,并且具有传入的父节点参数和属性参数。属性参数可选。创建失败返回null。
创建的对象和组件创建的上下文是同一个,如果调用的组件不是在QML中创建的,始终返回null。
如果不想传入parent参数,可以传null。注意,如果返回的对象用于展示,那必须提供一个有效的父节点参数,或者设置返回对象的parent属性,否则对象不可见。
如果没有提供parent参数,则必须持有返回对象的引用,防止垃圾回收。无论之后是否设置Item::parent,这都是正确的,因为设置Item parent并不会改变对象的所有权。只有图形父节点被更改。
从QtQuick 1.1开始,该方法接受一个可选的properties参数,该参数指定创建对象的初始属性值的映射。这些值在对象创建完成之前应用。这比在对象创建之后设置属性值更有效,特别是在定义了大量属性值的情况下,而且还允许在对象创建之前设置属性绑定(使用Qt.binding)。
properties参数被指定为键值对的映射。例如,下面的代码创建了一个对象,其初始x值和y值分别为100和100:
var component = Qt.createComponent("Button.qml");
if (component.status == Component.Ready)
component.createObject(parent, {x: 100, y: 100});
使用destroy()方法删除动态创建的实例。查看 Dynamic QML Object Creation from JavaScript。
string errorString()
返回可识别错误描述。
该字符串包括每个错误的文件、位置和描述。如果存在多个错误,则用换行符分隔。
如果没有错误,则返回一个空字符串。
object incubateObject(Item parent, object properties, enumeration mode)
为该组件的实例创建孵化器。孵化器允许新组件实例异步实例化,并且不会在UI中造成冻结。
parent参数指定创建实例的父节点。忽略参数或传递null将创建一个没有父对象的对象。在这种情况下,必须持有对已创建对象的引用,以便它不会被垃圾回收器销毁。
properties参数被指定为键值对的映射,该映射将在创建的对象的构造过程中设置。模式可以是Qt.Synchronous或Qt.Asynchronous,它控制实例是同步创建还是异步创建。默认是异步的。在某些情况下,即使指定了Qt.Synchronous,孵化器也可能异步地创建对象。如果调用incubateObject()的组件本身是异步创建的,就会发生这种情况。
这三个参数都是可选的。
如果成功,该方法将返回孵卵器,否则为空。孵化器具有以下特性:
- status 孵化器的状态,就是组件 的 Ready,Loading, Error状态
- object 创建的对象实例。只有在孵化器是Ready状态才可用。
- onStatusChanged 指定当状态改变时调用的回调函数。状态作为参数传递给回调函数。
- forceCompletion() 调用同步完成孵化器
下面的例子演示了如何使用孵化器:
var component = Qt.createComponent("Button.qml");
var 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 not ready!");
}
}
} else {
print("Object", incubator.object, "is ready immediately!");
}
使用destroy()方法删除动态创建的实例。查看 Dynamic QML Object Creation from JavaScript。