4.qml-Item元素学习

上章我们学习了3.qml-Rectangle组件学习

所以本章主要来讲解Rectangle的父类元素Item


1.Item介绍

如下图所示,我们可以看到Item是Qt中所有视觉项元素的父类, Qt中所有的视觉项目都从Item继承下来的,比如:Image(图像显示元素)、Rectangle(矩形元素)、Text(文本元素)、TextEdit(文本框元素)等等。

 4.qml-Item元素学习

而且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值的子项目要在同一片空间显示的话,默认是以它们初始化的顺序来显示,如下图所示(蓝色显示在红色的上面):

 4.qml-Item元素学习

如果是值不同,那么Z值越大,则显示在最上方.

 

2.2  clip属性

默认为false,那么如果子项目超出Item自身边框范围,也会被绘制.如果为true,那么将会被裁减.

代码如下所示:

Rectangle {
        width: 100
        height: 100
        border.width: 3
        border.color: "#000000"
        clip: true
        Rectangle {
            width: 70
            height: 70
            color: "red"
        }
        Rectangle {
            x: 50
            y: 50
            width: 70
            height: 70
            color: "yellow"
        }
}

设置clip为false时:

 4.qml-Item元素学习

设置clip为true时:

 4.qml-Item元素学习

 

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: 100
        height: 100
        border.width: 3
        border.color: "#000000"
        clip: true
        Rectangle {
            id: rect1
            width: 70
            height: 70
            color: "red"
        }
        Rectangle {
            id: rect2
            x: 50
            y: 50
            width: 70
            height: 70
            color: "yellow"
            visible: false  // 不显示
        }
 
        Component.onCompleted: {
            for(var i in data) {
                console.log("data[" + i + "]: ", data[i])
            }
            console.log("children length: ", children.length)       // 由于只有两个成员,所以打印2
            for(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)  // 由于有个成员不显示,所以打印1
            for(i = 0; i < visibleChildren.length; i++) {
                console.log("visibleChildren[" + i + "] 坐标:", visibleChildren[i].x, visibleChildren[i].y, visibleChildren[i].width, visibleChildren[i].height)
            }
        }
    }
运行打印:

4.qml-Item元素学习

其中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: 240
        height: 80
 
        Rectangle {
            id: rect1
            color: "red"
            anchors.alignWhenCentered: false
            anchors.centerIn : parent
            anchors.horizontalCenterOffset: -parent.width/3
            anchors.margins: 10
            width: 50
            height: 50
        }
        Rectangle {
            id: rect2
            color: "yellow"
            anchors.alignWhenCentered: false
            anchors.centerIn : parent
            anchors.margins: 10
            width: 50
            height: 50
        }
        Rectangle {
            id: rect3
            color: "lightsteelblue"
            anchors.centerIn : parent
            anchors.horizontalCenterOffset: parent.width/3
            anchors.margins: 10
            width: 50
            height: 50
        }
}
效果如下所示:
4.qml-Item元素学习

在上例中,我们通过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)等,如下图所示:
4.qml-Item元素学习

其中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: true
        Keys.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: true
        Keys.onPressed: {
            if ((event.key == Qt.Key_Space) && (event.modifiers & Qt.ShiftModifier))
                console.log("shift + space 被按下")
            event.accepted = true
        }
}

 

 

 
上一篇:【图像超分辨率】Perceptual Losses for Real-Time Style Transfer and Super-Resolution


下一篇:编写可读代码的艺术