2.QML组件、图像几何变换和元素定位器

一、组件

组件是可重用的元素,QML提供了不同的方式来创建组件。 最简单的组件是基于文件的组件。 通过在文件中放置QML元素并为该文件指定元素名称(例如Button.qml)来创建基于文件的组件。 然后导入该组件后,就可以像使用QtQuick模块中的其他元素一样使用该组件。组件文件的文件名的首字母开头一定要大写!!!

示例

//Button.qml
import QtQuick 2.12

Rectangle {
    id:buttonsize
    x:10
    y:10
    width:100
    height:30
    color: "red"
    border.color: "blue"
    property alias text: buttontext.text//自定义属性
    signal clicked

    Text {
        id: buttontext
        text: qsTr("button")
        anchors.centerIn: parent
    }

    MouseArea {
        anchors.fill: parent
        onClicked: {
            console.log("mouseare clicked")
            buttonsize.clicked()//触发clicked信号
        }
    }
}
Item {
    id: root
    width: 320
    height: 240

    Button {
        id:button1
        x:100
        y:status.y-status.height-10
        text: "Start"
        onClicked: {
           console.log("onclicked in main qml")
           status.text = "Button clicked!"
        }
    }

    Text {
        id: status
        text: qsTr("wait for pressing")//起始text
        elide: Text.ElideMiddle
        x:100
        y:100
        width: 150
        height: 40
    }
}

结果

上述代码在Button.qml中实现了一个组件button,在别的文件中,使用了该组件,当点击组件的mousearea时,会先触发组件的onclicked,并发出clicked信号,然后使用组件的文件中的onclicked相应该信号并修改text的状态,所以会先打印出qml: mouseare clicked,然后打印出qml: onclicked in main qml

组件类似于C++中的类。将类封装后,就可以使用类

 

二、元素几何变换

元素几何变换用于改变元素的几何形状。 QML可以对元素进行平移,旋转和缩放。x,y位置可以完成平移转换。 使用rotation属性实现旋转。 该值以度(0-360)为单位。 使用scale属性实现缩放,值<1表示元素按比例缩小,而值> 1表示元素按比例放大。 旋转和缩放不会更改几何形状。 x,y,width,height没有变。 只是绘画发生了变化。

示例

先定义一个图像组件

Image {
    id: root
    signal clicked

    MouseArea {
        id:mousearea
        anchors.fill: parent
        onClicked: {
            root.clicked()
        }
    }
}

接着进行元素变换

Item {
    id: root
    Image {
        id: bg
        source: "./background.png"
    }
    width: bg.width
    height: bg.height

    MouseArea {
        id:bgclicker
        anchors.fill:parent
        onClicked: {
            circle.x=84
            circle.y=84
            box.rotation=0
            triangle.scale=1
        }
    }

    Clickedimg {
        id:circle
        x:84
        y:68
        source: "./circle_blue.png"
        antialiasing: true
        onClicked: {
            x+=20
            y+=20
        }
    }

    Clickedimg {
        id:box
        x:164
        y:68
        source: "./box_green.png"
        antialiasing: true
        onClicked: {
            rotation+=30
        }
    }

    Clickedimg {
        id:triangle
        x:248
        y:68
        source: "./triangle_red.png"
        antialiasing: true
        onClicked: {
            scale+=0.1
        }
    }
}

效果如下

其中的antialiasing: true用于抗锯齿

此外,当三个元素彼此覆盖时,圆在最下,方形在中间,三角形在最上,因为Z方向的顺序和元素的代码的出现顺序有关。在代码中较早出现的元素具有较低的堆叠顺序(称为z方向顺序)。 z顺序也可以通过Item的z属性进行操作。鼠标区域的堆叠顺序也是如此。 在代码中较早出现的元素的鼠标区域将会被后出现的元素的鼠标区域覆盖。

 

三、元素的定位

定位器用来给qml元素进行位置锁定。QtQuick模块提供的定位器有Row, Column, Grid和Flow

示例

先实现三个颜色为红绿蓝的方块组件,代码如下

//Redsquare.qml
import QtQuick 2.0

Rectangle {
    id:redsquare
    width: 50
    height: 50
    color: "red"
    border.color: Qt.lighter(color)//Qt.lighter(color)可以根据填充颜色产生较浅的边框颜色。
}
//Bluesquare.qml
import QtQuick 2.0

Rectangle {
    id:redsquare
    width: 50
    height: 50
    color: "blue"
    border.color: Qt.lighter(color)//Qt.lighter(color)可以根据填充颜色产生较浅的边框颜色。
}
//Greensquare.qml
import QtQuick 2.0

Rectangle {
    id:redsquare
    width: 50
    height: 50
    color: "green"
    border.color: Qt.lighter(color)//Qt.lighter(color)可以根据填充颜色产生较浅的边框颜色。
}

上述三个组件只不过颜色不同,其他完全相同,组件实现完后,分别演示四种定位器

1.Row

Rectangle {
    id:root
    width: 320
    height: 240

    Row {
        id:row
        anchors.centerIn: parent
        spacing: 15//控制元素的间距
        Redsquare {}
        Bluesquare {}
        Greensquare {}
    }
}

 

2.Column

Rectangle {
    id:root
    width: 320
    height: 240

    Column {
        id:col
        anchors.centerIn: parent//元素位于父元素的中央位置
        spacing: 15
        Redsquare {}
        Bluesquare {
            width: 100
        }
        Greensquare {}
    }
}

定位器Row和Column的代码几乎都是一样的,Grid的代码略有不同;Grid通过设置rowscolumns属性将元素排列在网格中。 如果不设置columnsrows,则根据columnsrows数量来计算另一个。 例如,将行设置为3并添加6个元素,那么列将自动为2。 属性flow和layoutDirection用于控制元素添加到Grid的顺序,而spacing还是控制元素的间距。

 

3.Grid

Rectangle {
    id:root
    width: 320
    height: 240

    Grid {
        id:grid
        anchors.centerIn: parent
        spacing: 10
        columns: 2
        rows: 2
        Redsquare {}
        Redsquare {}
        Redsquare {}
        Redsquare {}
    }
}

 

4.Flow

Flow将元素添加到流中。 使用flow和layoutDirection属性元素的排列的方向。这样,元素可以横向或者纵向排列。将元素添加到流中时,可以根据需要,将它们包装起来形成新的行或列。 为了使Flow工作,必须具有宽度或高度。 可以直接通过属性设置,也可以通过锚定布局设置。

示例

Rectangle {
    id:root
    width: 320
    height: 240
    Flow {
        anchors.fill: parent
        anchors.margins: 20
        spacing: 10
        flow: Flow.LeftToRight
        //flow: Flow.TopToBottom
        Redsquare{}
        Bluesquare {}
        Greensquare {}
        Redsquare {}
    }
}

flow属性如果不设置的话,默认就是Flow.LeftToRight,可以设置为Flow.TopToBottom,效果如下

其中的margin是关于布局的,后面再说

 

上述代码最多只添加了四个元素,但是,如果要添加100个元素总不能一个一个敲吧?和定位器经常一起使用的元素是Repeater。 Repeater类似一个for循环。 在最简单的情况下,Repeater只是通过model属性提供循环次数

示例

Rectangle {
    id:root
    width: 250
    height: 250
    property var colorarray: ["red", "green", "blue"]
    Grid {
        id:grid
        anchors.fill: parent
        anchors.margins: 15
        spacing: 5
        Repeater {
            model: 16
            Rectangle {
                width: 50
                height: 50
                property int colorindex: Math.floor(Math.random()*3)
                color: root.colorarray[colorindex]
                border.color: Qt.lighter(color)
                Text {
                    id: name
                    text: qsTr("ceil")+index
                    color: "white"
                    anchors.centerIn: parent
                }
            }
        }
    }
}

对于每个循环,Repeater都会创建一个方块。 在方块中,通过JS的函数Math.floor(Math.random()* 3)选择颜色。 Math.random()的返回值是一个大于等于0小于1的随机数,所以floor(Math.random()* 3)向下取整,提供了一个介于0-2之间的随机数,因此可以从颜色数组中选择颜色。 此外,循环时,Repeater将会生成index。 它包含当前的循环索引(0,1,.. 15)。

显示结果如下

 

参考

《qml book》

 

欢迎大家评论交流,作者水平有限,如有错误,欢迎指出

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值