1. 简述
1.1. Compent是什么?
翻译过来就是组件,如Button、Label,都是组件,通常由一个.qml文件实现,而文件名就是组件的名称。
在C++中,我们实现一个由多个子组件构成的复杂的组件,可以在一个cpp文件中实现,一个cpp可是写多个类的实现。但qml文件中只允许存在一个根节点,可以理解为只能实现一个类。但借助Component,你可以在qml文件中定义内联组件,达到代码复用目的。可以理解为类中子类。
Component可以做什么?
在qml文件中实现组件的子组件,而不必新建qml文件。
1.2. Loader是什么?
Loader用来动态加载QML组件,我们使用Compent实现的组件,不会被创建出来,此时借助Loader可以加载出来
2. 示例:内联组件实现
如图,实现一个区域选择器
有8个锚点,样式一样,我们不想写8个Rectangle,因为修改锚点颜色或者样式要修改8处代码。也达不到代码复用的目的。可以声明一个内联锚点类,用Loader创建8次就行
Item{
id: root
//矩形边框
Rectanglg{
anchors.fill: parent
...
}
//锚点组件
Component{
id: _rectAnchor
MouseArea {
hoverEnabled: true
cursorShape: Qt.SizeVerCursor
Rectangle{
anchors.centerIn: parent
width: root.handleWidth
height: root.handleWidth
color: root.color
border.color: "white"
border.width: 1
}
}
}
//8个锚点
Loader{
anchors.top: root.top
anchors.left: root.left
sourceComponent: _rectAnchor //加载锚点组件
}
Loader{
...
}
Loader{
...
}
...
}
}
3. Loader连接Compent的信号、设置属性
Component{
id: _mouseArea
...
MouseArea {
hoverEnabled: true
signal moved(int moveX, int moveY)
cursorShape: Qt.SizeVerCursor
onPositionChanged: {
if (pressed) {
moved(mouseX , mouseY)
}
}
}
}
//实例化一个_mouseArea组件
Loader{
id: _loaderTop
sourceComponent: _mouseArea
onLoaded: item.cursorShape = Qt.SizeHorCursor //load完成设置通过item属性设置_mouseArea的光标形状
Connections{
target: _loaderTop.item
onMoved:{ //连接_mouseArea的moved信号
...
}
}
}
4. 内置信号使用
最2个常用的信号。如果我们希望组件创建完成的时候执行一些代码进行初始化,在c++中你可以在构造函数中执行初始化代码。但qml没有构造函数。不过他有对象创建完成的信号,写个信号处理函数即可,如下
//显示天气的Text
Text{
id:textWeather
text: qsTr("未知")
//对象实例化完成的信号
Component.onCompleted:{
//获取天气
textWeather.text = ...
}
//对象释放的信号
Component.onDestruction: {
console.log("对象释放")
}
}