4.qml-Item元素学习
所以本章主要来讲解Rectangle的父类元素Item
1.Item介绍
如下图所示,我们可以看到Item是Qt中所有视觉项元素的父类, Qt中所有的视觉项目都从Item继承下来的,比如:Image(图像显示元素)、Rectangle(矩形元素)、Text(文本元素)、TextEdit(文本框元素)等等。
而且Item为所有视觉项提供了常见的属性,如x和y位置、宽度和高度、锚和key事件处理支持。
2. Item-常用属性介绍
Item提供的常用属性如下所示:
x : real,指定元素的X坐标
y : real,指定元素的Y坐标
z : real,指定元素的堆叠顺序,
width : real,指定元素的宽度
height : real,指定元素的高度
implicitHeight : real,指定元素的隐式高度
implicitWidth : real, 指定元素的隐式宽度
[default] data : list<Object>,data属性, 它是个默认属性,所有的子项都被自动分配给这个属性,所以不需要被赋值
clip : bool,指定裁剪属性,默认为false,如果设置为true,那么超出Item自身边框的绘图或者子项目,都会被裁减掉.
visible : bool,设置元素是否可见,默认为true.如果在Item自身元素下设置该属性,会直接影响到子项目的可见值。使用该属性时,最好不要使用apacity属性.
visibleChildren : list<Item>,保存当前可见的所有子项目
children : list<Item>,保存所有子项目
opacity : real,透明度,默认值为1.0,如果设置为0.0则表示全透明, 如果在Item自身元素下设置该属性,会直接影响到子项目的透明值。
rotation : real,设置元素的顺时针旋转度数
scale : real,缩放值,值小于1缩小显示;大于1放大显示;负值则是镜像效果
transformOrigin : scale缩放时的基点位置,默认值为Center
2.1 z属性
z用来设置每个子项目的堆叠显示顺序,默认值为0,如果相同Z值的子项目要在同一片空间显示的话,默认是以它们初始化的顺序来显示,如下图所示(蓝色显示在红色的上面):
如果是值不同,那么Z值越大,则显示在最上方.
2.2 clip属性
默认为false,那么如果子项目超出Item自身边框范围,也会被绘制.如果为true,那么将会被裁减.
代码如下所示:
Rectangle { width: 100height: 100border.width: 3border.color: "#000000"clip: trueRectangle { width: 70height: 70color: "red"} Rectangle { x: 50y: 50width: 70height: 70color: "yellow"}}
设置clip为false时:
设置clip为true时:
2.3 打印children子元素成员
在QML中,如果属性值是list类型的,都可以使用[]方括号来访问列表成员.
并且list提供了一个length 属性,可以让我们获取列表中的数量
还可以使用push方法将值添加到列表中,就像它是JavaScript数组一样
并且列表只能存储QML对象,并且不能包含任何基本类型值(int,string等)。
如果要在列表中存储基本类型,则需要使用var类型
所以我们for循环打印的写法有两种:
for(var i = 0; i < data.length; i++) { ... ...} // 正常写法for(var i in data) { ... ... } // javascript写法
示例如下所示:
Rectangle { id: group width: 100height: 100border.width: 3border.color: "#000000"clip: trueRectangle { id: rect1 width: 70height: 70color: "red"} Rectangle { id: rect2 x: 50y: 50width: 70height: 70color: "yellow"visible: false // 不显示 } Component.onCompleted: {for(var i in data) { console.log("data[" + i + "]: ", data[i]) } console.log("children length: ", children.length) // 由于只有两个成员,所以打印2for(i = 0; i < children.length; i++) { console.log("children[" + i + "] 坐标:", children[i].x, children[i].y, children[i].width, children[i].height) } console.log("children length: ", visibleChildren.length) // 由于有个成员不显示,所以打印1for(i = 0; i < visibleChildren.length; i++) { console.log("visibleChildren[" + i + "] 坐标:", visibleChildren[i].x, visibleChildren[i].y, visibleChildren[i].width, visibleChildren[i].height) } } }
运行打印:
其中Component.onCompleted是个槽函数,当我们实例化完成后, Component就会发出completed信号,然后触发onCompleted槽函数
3.Item-Anchors锚
Anchors锚在Item中相当重要,通过它来指定每个元素与其它元素之间的位置方向,从而可以实现相对布局。
Anchors提供向Item下面几种属性:
anchors.top : AnchorLine,指定元素的顶部与哪个瞄线对齐
anchors.bottom : AnchorLine,指定元素的底部与哪个瞄线对齐
anchors.left : AnchorLine,指定元素的左侧与哪个瞄线对齐
anchors.right : AnchorLine,指定元素右侧与哪个瞄线对齐
anchors.horizontalCenter : AnchorLine,指定元素与哪个瞄线进行水平居中
anchors.verticalCenter : AnchorLine,指定元素与哪个瞄线进行垂直居中
anchors.baseline : AnchorLine,指定元素里的文本基线与哪个瞄线对齐(实际就是文本的顶部)
anchors.fill : Item,指定元素填满在哪个Item下面,但是使用该属性后,再设置自身元素width和height是无效果的
anchors.centerIn : Item,指定元素的中心点放在哪个Item下面进行居中对齐,也可以填anchors.top之类的描线,比如anchors.centerIn : rect1.right
anchors.margins : real,设置元素的所有外边框的宽度
anchors.topMargin : real
anchors.bottomMargin : real
anchors.leftMargin : real
anchors.rightMargin : real
anchors.horizontalCenterOffset : real,设置元素的水平居中的左右偏移值
anchors.verticalCenterOffset : real,设置元素的垂直居中的上下偏移值
anchors.baselineOffset : real,设置文本基线的偏移值
anchors.alignWhenCentered : bool,强制居中,默认为true, 假如宽或者高为奇数时,如果中心对齐, 就可以保证绝对对齐。
示例1-实现3个子元素水平布局
Rectangle { color: "blue"width: 240height: 80 Rectangle { id: rect1 color: "red"anchors.alignWhenCentered: falseanchors.centerIn : parent anchors.horizontalCenterOffset: -parent.width/3anchors.margins: 10width: 50height: 50} Rectangle { id: rect2 color: "yellow"anchors.alignWhenCentered: falseanchors.centerIn : parent anchors.margins: 10width: 50height: 50} Rectangle { id: rect3 color: "lightsteelblue"anchors.centerIn : parent anchors.horizontalCenterOffset: parent.width/3anchors.margins: 10width: 50height: 50}}
效果如下所示:
在上例中,我们通过anchors.centerIn : parent,让3个元素都居中,然后通过anchors.horizontalCenterOffset来实现左右偏移.
注意 - anchors.centerIn : parent 本质上就是垂直水平居中,等价于:
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
提示: 在后面我们学习Item的子元素时候,就用Row、Column来实现布局.
4. Item-key事件处理
Item通过“key”附加属性可以让所有基于Item的元素都可以使用键处理。Keys附加属性提供了:基本信号,如pressed(event) 和released(event),以及特定按键的信号,比如spacePressed(event)等,如下图所示:
其中event参数包含了按键的详细信息.该参数类型是KeyEvent.如果我们检测到按键是我们所需要的,则需要将accepted设置为true防止该按键事件传播到父级。从而让父级不会对同一事件做出响应。
4.1 Keys属性使用示例
下面我们演示如何检测空格键按下:
Item { anchors.fill: parent focus: true Keys.onPressed: { if (event.key == Qt.Key_Space) { console.log("空格键按下"); event.accepted = true; } } }
其实我们还可以写的更加简洁,使用特定键信号来接收,这里它会自动将event.accepted设置为true:
Item { anchors.fill: parent focus: trueKeys.onSpacePressed: console.log("空格键按下")}
4.2 KeyEvent深入讲解
在上节,我们只是简单学习了如何获取key事件,本节,我们来深入学习如何使用组合按键(比如:ctrl+a).
event的参数类型是KeyEvent,它的属性有:
accepted : bool, 按键是否被接受,如果设置为true,则表示已经接受该事件处理,那么该事件就不会再传播到父级。从而让父级不会对同一事件做出响应。
text : string, 返回按键按下的字符串名字,比如按下1键,那么text="1",也有可能是空白字符串.
count : int, 返回text字符串的长度。
isAutoRepeat : bool, 用来检测一直按下未松开的按键事件.如果为true则表示为松开.
key : int,键盘码的标识,参考Qt::Key枚举值,比如Qt::Key_Tab
modifiers : int, 此属性保存键盘的修饰符标志,比如Qt::ShiftModifier(shift按键被按下)
nativeScanCode : quint32,键盘扫描码,区分不同的相同key名按键,比如左侧shift键和右侧shift键,它们的key值是一样,但是nativeScanCode是不一样的.
组合按键检测示例如下所示:
Item { anchors.fill: parent focus: trueKeys.onPressed: {if ((event.key == Qt.Key_Space) && (event.modifiers & Qt.ShiftModifier)) console.log("shift + space 被按下")event.accepted = true}}
注意-附加属性的槽函数(信号处理器)
刚刚我们学习了Item的"Key"附加属性,并使用它的信号处理器处理按键,其实都是按照<附加属性>.on<Signal>语法实现的.必须得严格遵守,因为附加属性不属于该元素自身的属性.
如果是使用普通的信号处理器(基类或者自身的信号发射的),则直接用on<Signal>语法实现.
在后面,我们会学习自定义信号,以及信号与槽的连接.END