学习过qml的都知道,在qml中是无法定义“私有变量”的;
在自定义的控件内部定义的变量,在调用者外部是可以被使用,这不符合某些情况下的项目需求,那么该如何取巧的解决这个问题呢?
有的,可通过QtObject控件实现。
官方文档介绍:
The QtObject type is a non-visual element which contains only the objectName property.
It can be useful to create a QtObject if you need an extremely lightweight type to enclose a set of custom properties.
案例场景:
首先我们新建一个MyRectangle.qml文件,在文件内实现一个自定义的简易的Rectangle控件;
内部有定义变量供外部调用者使用;如下:
// MyRectangle.qml
import QtQuick 2.0
Rectangle {
id: borderRect
property int innerTopMargin: 1 // 上边距
property int innerBottomMargin: 1 // 下边距
property int innerLeftMargin: 1 // 左边距
property int innerRightMargin: 1 // 右边距
property string innerColor: "white" // 矩形颜色
property string bodercolor: "black" // 边框颜色
width: 100
height: 50
color: bodercolor
Rectangle {
id: innerRect
color: innerColor
z:1
anchors.fill: parent // 填充满父类
anchors.topMargin: innerTopMargin
anchors.bottomMargin: innerBottomMargin
anchors.leftMargin: innerLeftMargin
anchors.rightMargin: innerRightMargin
}
}
然后在main.qml文件内可以直接使用:
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.14
Window {
id: root
visible: true
width: SCREEN_WIDTH
height: 500
title: qsTr("Hello World")
color: "white"
MyRectangle {
x: 100
y: 200
width: 300
height: 200
// 可以在调用者外部直接使用内部定义变量
innerColor: "yellow"
}
}
可以看到,在外部,即调用者处,直接使用了innerColor变量对矩形的颜色做了修改;
假设我们不希望矩形的内部的颜色被修改,那么,就得将innerColor变量设置为“私有变量”;这时候,QtObject就排上用用场。
在MyRectangle.qml文件内,定义QtObject控件,并将innerColor变量的定义放入到QtObject控件内。
// MyRectangle.qml
// 可通过定义QtObject控件,在控件内部定义变量,从而实现私有变量的效果
QtObject {
id: attributes
property string innerColor: "white" // 矩形颜色
}
此时,在调用者处,已经发生了报错:
当然,其他的变量还是可以正常使用的,例如将矩形的边框颜色修改为红色(bodercolor: "red"),然后注释掉报错代码,(// innerColor: "yellow"),运行截图:
那么,在MyRectangle.qml文件内如何使用QtObject内定义的变量呢?
其实,可以直接使用QtObject的id值去使用到其内部定义的变量!
例如,在自定义控件MyRectangle被构建之后,使用QtObject的id值调用innerColor,将矩形背景颜色修改为灰色;
// MyRectangle.qml
// 在QtObject外部如果需要使用,则可以使用id直接使用
Component.onCompleted: {
attributes.innerColor = "gray" // 修改矩形颜色为灰色
console.log("innerColor:", attributes.innerColor);
}
可以看出,在MyRectangle.qml文件内,我们使用attributes.innerColor确实可以对在QtObject内定义的变量做修改;而且在调用者处,也确实是修改不了innerColor变量了,innerColor实际上变成了“私有变量”。
如果说,期望在调用者处也能使用innerColor变量,这该如何处理呢?
还是有一个办法,将id值attributes通过别名方式暴露给外部使用!
在MyRectangle.qml文件内,给attributes定义别名:
// 可通过别名的方式给外部提供内部变量的父id,就可以外部使用到内部的变量的
property alias attr: attributes
那么在调用者处,就可以直接使用attr调用到innerColor变量了;
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.14
Window {
id: root
visible: true
width: SCREEN_WIDTH
height: 500
title: qsTr("Hello World")
color: "white"
MyRectangle {
x: 100
y: 200
width: 300
height: 200
// 可以在调用者外部直接使用内部定义变量
// innerColor: "yellow"
bodercolor: "red"
// 通过别名方式可使用内部的变量
Component.onCompleted: {
attr.innerColor = "green" // 修改矩形颜色为绿色
console.log("innerColor:", attr.innerColor);
}
}
}
通过使用别名方式,真的就使用到了innerColor变量了。
上述就是介绍了在qml中如何定义“私有变量”的全部过程,通过使用QtObject可以取巧定义到“私有变量”,因为qml本身并不支持定义私有变量。
最后附上MyRectangle.qml文件全部代码:
import QtQuick 2.0
Rectangle {
id: borderRect
property int innerTopMargin: 1 // 上边距
property int innerBottomMargin: 1 // 下边距
property int innerLeftMargin: 1 // 左边距
property int innerRightMargin: 1 // 右边距
property string bodercolor: "black" // 边框颜色
width: 100
height: 50
color: bodercolor
// 可通过别名的方式给外部提供内部变量的父id,就可以外部使用到内部的变量的
property alias attr: attributes
Rectangle {
id: innerRect
color: attributes.innerColor
z:1
anchors.fill: parent // 填充满父类
anchors.topMargin: innerTopMargin
anchors.bottomMargin: innerBottomMargin
anchors.leftMargin: innerLeftMargin
anchors.rightMargin: innerRightMargin
}
// 可通过定义QtObject控件,在控件内部定义变量,从而实现私有变量的效果
QtObject {
id: attributes
property string innerColor: "white" // 矩形颜色
}
// 在QtObject外部如果需要使用,则可以使用id直接使用
Component.onCompleted: {
attributes.innerColor = "gray" // 修改矩形颜色为灰色
console.log("innerColor:", attributes.innerColor);
}
}