QML界面控件加载与显示顺序
一、QML界面控件加载顺序
QML在界面加载时的顺序和我们认知的有很大的不同,有时候会对我们获取参数以及界面实现造成很大的困扰
1、加载顺序
import QtQuick 2.12 import QtQml 2.12 import QtQuick.Window 2.12 import QtQuick.VirtualKeyboard 2.4 Window { id: window width: 800 height: 480 visible: true title: qsTr("Hello World") Component.onCompleted: { console.log("Window success") // 2 } Item { Component.onCompleted: { console.log("Item success") // 7 } } Rectangle { anchors.fill: parent color: "red" Row { Repeater { model: 3 Text { width: 100 height: 50 font.pixelSize: 30 color: "blue" horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter text: qsTr("text") Component.onCompleted: { console.log("text success") // 1 } } Component.onCompleted: { console.log("Repeater success") // 6 } } Component.onCompleted: { console.log("Row success") // 5 } } Component.onCompleted: { console.log("Rectangle success") // 4 } } InputPanel { id: inputPanel z: 99 x: 0 y: window.height width: window.width states: State { name: "visible" when: inputPanel.active PropertyChanges { target: inputPanel y: window.height - inputPanel.height } } transitions: Transition { from: "" to: "visible" reversible: true ParallelAnimation { NumberAnimation { properties: "y" duration: 250 easing.type: Easing.InOutQuad } } } Component.onCompleted: { console.log("InputPanel success") // 3 } } }
运行上面代码后调试信息如下:
总结:
除C++模块外,先是加载界面内的Repeater中重复的内容!!!!
再加载界面本身
然后按照从下到上,由外到内的加载,但是界面展示的顺序是由上到下!!!!
(信号的改变以及loader需要加载的都是优先加载的)
信号的改变高于界面本身的加载
2、影响
由于Repeater中重复的控件是最先被加载的,所以如果在加载的时候给控件赋初值,而这个值又是从C++端获取的参数,这时能否赋值成功取决于从C++获取参数的方式,如下第一种方式可以,第二种就会有问题
(1)导入c++的Object模块,实例化类对象,参数(类成员变量)在类的定义中使用 Q_PROPERTY 声明过。qml在任何时候调用被Q_PROPERTY宏修饰过参数都是不影响的
例1:
类定义:
Q_PROPERTY(int sampMode READ getSampMode WRITE setSampMode NOTIFY paraChanged) Q_PROPERTY(int offerMode READ getOfferMode WRITE setOfferMode NOTIFY paraChanged)
例2:
(2)通过函数等方法传递 的参数就要注意了,函数调用的时机就尤为重要,必须在控件加载前调用!!!如下:
- C++返回一个QVariantList类型的值给到qml端
- Qml导入模块调用函数获取返回值
- 根据加载顺序,这个时候在加载repeater的时候如果调用返回值的话,就会调用失败
但如果将 通过函数获取的C++参数绑定到一个变量上,qml通过变量来获取C++参数的话,也是可以的。如下:
二、QML界面显示顺序
qml会先将界面中的控件加载完成再显示,加载的顺序并不是界面的显示顺序,界面显示的顺序是由上到下的!!! 如下代码,实现一个点击编辑框后弹出键盘,同时整个界面整体往上推,将编辑框显示在键盘外面,以至不被键盘隐藏住
子界面会先显示出来,title后显示,当然人眼肯定是看不出来显示顺序的。如果想实现点击编辑框,弹出键盘,同时将子界面往上移,但又不能超过title的功能,就需要将title放置在子界面的下面或将title的z调高,因为键盘往上推的时候,实际是改变了子界面的y,那么在改变后重新显示的时候,如果title与子界面有了重叠,按照显示顺序,title要是在上面就会被子界面覆盖掉(看着是被一起往上推了,实则是被覆盖住了)
- 根据加载顺序,这个时候在加载repeater的时候如果调用返回值的话,就会调用失败
- Qml导入模块调用函数获取返回值