项目越大,我们肯定需要动态进行加载,否则程序会变得越来越慢。本文主要是记录项目过程中使用Loader 来加载。
本文主要从以下几个方面来进行简述动态加载:
一、Loader加载的方式。
Loader 用来动态加载QML组件,可以看作是一种占位符,可以加载一个QML文件或者一个组件对象。加载一个QML文件使用 source属性,加载组件对象使用sourceComponent属性。如果source 或者sourceComponent更改了,先前实例化的项目将被销毁。将source设置位空字符串或者将sourceComponent设置为undefined,都会销毁当前加载的项目并释放资源。
示例加载qml文件:
Window{
id:root
width:1920
height:1080
visible:true
title:qsTr("动态加载QML文档")
Loader{
id:loaderFile
anchors.fill:parent
}
Button{
id:button1
anchors.left:parent.left
anchors.leftMargin:100
anchors.top:parent.top
anchors.topMargin:100
text:qsTr("加载设置界面")
//开始动态加载 qml 文当
loaderFile.source = "SetParameter.qml"
}
Button{
id:button2
anchors.left:button1.right
anchors.leftMargin:100
anchors.top:parent.top
anchors.topMargin:100
text:qsTr("退出设置界面")
//销毁动态加载的SetParameter.qml 对象
loaderFile.source = ""
}
}
示例加载QML组件:
Window{
id:root
width:1920
height:1080
visible:true
title:qsTr("动态加载QML组件")
Loader{
id:loaderModule
}
Component{
id:testModule
Rectangle{
width:100
height:100
color:"blue"
}
}
Button{
id:button1
anchors.left:parent.left
anchors.leftMargin:100
anchors.top:parent.top
anchors.topMargin:100
text:qsTr("加载设置界面")
//开始动态加载 qml 组件
loaderFile.sourceComponent = loaderModule
}
Button{
id:button2
anchors.left:button1.right
anchors.leftMargin:100
anchors.top:parent.top
anchors.topMargin:100
text:qsTr("退出设置界面")
//销毁动态加载的qml 对象
loaderFile.sourceComponent = ""
}
}
二、Loader加载的组件大小。
如果source组件不是Item类型的,Loader不会使用任何大小规则,当加载可视化类型时,Loader会依据如下的大小规则:
1、如果没有明确指定Loader的大小,那么Loader将会在组件加载完成后自动设置为组件的大小。
Window{
id:root
width:1920
height:1080
visible:true
title:qsTr("动态加载QML组件")
Loader{
id:loaderModule
//Loader 没有明确指定大小,那么我们加载的组件大小为testModule 中的width:100,
//height:100
}
Component{
id:testModule
Rectangle{
width:100
height:100
color:"blue"
}
}
Button{
id:button1
anchors.left:parent.left
anchors.leftMargin:100
anchors.top:parent.top
anchors.topMargin:100
text:qsTr("加载设置界面")
//开始动态加载 qml 组件
loaderFile.sourceComponent = loaderModule
}
Button{
id:button2
anchors.left:button1.right
anchors.leftMargin:100
anchors.top:parent.top
anchors.topMargin:100
text:qsTr("退出设置界面")
//销毁动态加载的qml 对象
loaderFile.sourceComponent = ""
}
}
2、如果通过设置width,height 或者使用锚明确指定Loader的大小,那么被加载的项目将会适配为Loader的大小
Window{
id:root
width:1920
height:1080
visible:true
title:qsTr("动态加载QML组件")
Loader{
id:loaderModule
anchor.left:parent.left
anchor.top:parent.top
width:200
height:200
//Loader 明确指定大小,那么我们加载的组件大小为Loader指定的大小width:200 height:200
}
Component{
id:testModule
Rectangle{
width:100 //loader 指定大小,此大小失效
height:100
color:"blue"
}
}
Button{
id:button1
anchors.left:parent.left
anchors.leftMargin:100
anchors.top:parent.top
anchors.topMargin:100
text:qsTr("加载设置界面")
//开始动态加载 qml 组件
loaderFile.sourceComponent = loaderModule
}
Button{
id:button2
anchors.left:button1.right
anchors.leftMargin:100
anchors.top:parent.top
anchors.topMargin:100
text:qsTr("退出设置界面")
//销毁动态加载的qml 对象
loaderFile.sourceComponent = ""
}
}
三、Loader 加载的信息传递。
在本项目中我们使用了三种信息传递的方式。
1、在C++中定义一个单例类并把这个单例类注册到QML中,这样我们可以完成C++和QML间的消息传递。
2、被加载的类的消息传递给Loader或父项目。
3、Loader 或父项目中的信息传递给被加载的文档或组件。
注:详细代码请订阅后私信获取
四、焦点和键盘事件
Loader是一个焦点作用域,要使它的任何子项目获得活动焦点,都必须将其focus属性设置为true.任何被加载的项目获得的键盘事件都需要设置accepted为true,从而使他们不会传播到Loader.
Window{
id:root
width:1920
height:1080
visible:true
title:qsTr("动态加载QML文档")
Loader{
id:loaderFile
anchors.fill:parent
focus:true //必须设置为true,子项目才能获得活动焦点
}
Button{
id:button1
anchors.left:parent.left
anchors.leftMargin:100
anchors.top:parent.top
anchors.topMargin:100
text:qsTr("加载设置界面")
//开始动态加载 qml 文当
loaderFile.source = "SetParameter.qml"
}
Button{
id:button2
anchors.left:button1.right
anchors.leftMargin:100
anchors.top:parent.top
anchors.topMargin:100
text:qsTr("退出设置界面")
//销毁动态加载的SetParameter.qml 对象
loaderFile.source = ""
}
}
//SetParameter.qml
Item{
Rectangle{
focus:true;
Keys.onPressed:{
event.accepted = true; //设置为true,才不会使活动焦点传递到loader中去
}
}
}