一、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要是在上面就会被子界面覆盖掉(看着是被一起往上推了,实则是被覆盖住了)