分享

4.qml-Item元素学习

 悦光阴 2021-04-26

所以本章主要来讲解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 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多