QML

1、快速入门

基础语法:

a. import声明导入了一个指定的模块版本。一般来说会导入QtQuick2.0来作为初始元素的引用。
b. 使用//可以单行注释,使用/**/可以多行注释,就像C/C++和JavaScript一样。
c. 每一个QML文件都需要一个根元素,就像HTML一样。
d. 一个元素使用它的类型声明,然后使用{}进行包含。
e. 元素拥有属性,他们按照name:value的格式来赋值。
f. 任何在QML文档中的元素都可以使用它们的id进行访问(id是一个任意的标识符)。
g. 元素可以嵌套,这意味着一个父元素可以拥有多个子元素。子元素可以通过访问parent关键字来访问它们的父元素。

基本元素:

元素名称元素描述
Item(基础元素对象) 
Rectangle (矩形框元素) 
Text(文本元素) 
Image(图像元素) 
MouseArea(鼠标区域元素) 

组件:一个组件是一个可以重复使用的元素,QML提供几种不同的方法来创建组件。一个文件就是一个基础组件。

简单的切换:

定位元素:

布局元素:

输入元素:

高级用法:

2、动态元素

动画:

状态与过渡:

在QML中,使用State元素来定义状态,需要与基础元素对象(Item)的states序列属性连接。状态通过它的状态名来鉴别,由组成它的一系列简单的属性来改变元素。默认的状态在初始化元素属性时定义,并命名为“”(一个空的字符串)。

Item {
    id: root
    states: [
        State {
            name: "go"
            PropertyChanges { ... }
        },
        State {
            name: "stop"
            PropertyChanges { ... }
        }
    ]
}

 状态的改变由分配一个元素新的状态属性名来完成。
        注意:另一种切换属性的方法是使用状态元素的when属性。when属性能够被设置为一个表达式的结果,当结果为true时,状态被使用。

Item {
    id: root
    states: [
    ...
    ]
    Button {
        id: goButton
        ...
        onClicked: root.state = "go"
    }
}

Rectangle {
    id: light1
    x: 25; y: 15
    width: 100; height: width
    radius: width/2
    color: "black"
}
Rectangle {
    id: light2
    x: 25; y: 135
    width: 100; height: width
    radius: width/2
    color: "black"
}

state: "stop"
states: [
    State {
        name: "stop"
        PropertyChanges { target: light1; color: "red" }
        PropertyChanges { target: light2; color: "black" }
    },
    State {
        name: "go"
        PropertyChanges { target: light1; color: "black" }
        PropertyChanges { target: light2; color: "green" }
    }
]

MouseArea {
    anchors.fill: parent
    onClicked: parent.state = (parent.state == "stop"? "go" : "stop")
}

  过渡:一系列的过渡能够被加入任何元素,一个过渡由状态的改变触发执行。你可以使用属性的from:和to:来定义状态改变的指定过渡。这两个属性就像一个过滤器,当过滤器为true时,过渡生效。也可以使用“”来表示任何状态。例如from:""; to:"*"表示从
任一状态到另一个任一状态的默认值,这意味着过渡用于每个状态的切换。

transitions: [
    Transition {
        from: "stop"; to: "go"
        ColorAnimation { target: light1; properties: "color"; duration: }
        ColorAnimation { target: light2; properties: "color"; duration: }
]

高级用法:

3、模型-视图-代理

在QtQuick中,数据通过model-view(模型-视图)分离。对于每个view(视图),每个数据元素的可视化都分给一个代理(delegate)。在QML中,model(模型)与view(视图)都通过delegate(代理)连接起来。

显示在view(视图)中的每项数据,都是通过delegate(代理)来实现可视化。view(视图)的任务是排列这些delegate(代理),每个delegate(代理)将modelitem(模型项)的值显示给用户。
    基础模型:

最基本的分离数据与显示的方法是使用Repeater元素。它被用于实例化一组元素项,并且很容易与一个用于填充用户界面的定位器相结合。最基本的实现举例,repeater元素用于实现子元素的标号。每个子元素都拥有一个可以访问的属性index,用于区分不同的子元素。

import QtQuick 2.0

Column {
    spacing: 2
    Repeater {
        model: 10
        Rectangle {
            width: 100
            height: 20
            radius: 3
            color: "lightBlue"
            Text {
                anchors.centerIn: parent
                text: index
            }
        }
    }
}


Column {
    spacing: 2
    Repeater {
        model: [
            "Enterprise", "Colombia", "Challenger", "Discovery", "Endeavour", "Atlantis"
        ]
        Rectangle {
            width: 100
            height: 20
            radius: 3
            color: "lightBlue"
            Text {
                anchors.centerIn: parent
                text: index +": "+modelData
            }
        }
    }
}


Column {
    spacing: 2
    Repeater {
        model: ListModel {
            ListElement { name: "Mercury"; surfaceColor: "gray" }
            ListElement { name: "Venus"; surfaceColor: "yellow" }
            ListElement { name: "Earth"; surfaceColor: "blue" }
            ListElement { name: "Mars"; surfaceColor: "orange" }
            ListElement { name: "Jupiter"; surfaceColor: "orange" }
            ListElement { name: "Saturn"; surfaceColor: "yellow" }
            ListElement { name: "Uranus"; surfaceColor: "lightBlue" }
            ListElement { name: "Neptune"; surfaceColor: "lightBlue" }
        }

        Rectangle {
            width: 100
            height: 20
            radius: 3
            color: "lightBlue"
            Text {
            anchors.centerIn: parent
            text: name
            }
            Rectangle {
                anchors.left: parent.left
                anchors.verticalCenter: parent.verticalCenter
                anchors.leftMargin: 2
                width: 16
                height: 16
                radius: 8
                border.color: "black"
                border.width: 1
                color: surfaceColor
            }
        }
    }
}

repeater的内容的每个子项实例化时绑定了默认的属性delegate(代理)。

动态视图:

        Repeater元素适合有限的静态数据,但是在真正使用时,模型通常更加复杂和庞大,我们需要一个更加智能的解决方案。QtQuick提供了ListView和GridView元素,这两个都是基于Flickable(可滑动)区域的元素,因此用户可以放入更大的数据。
同时,它们限制了同时实例化的代理数量。对于一个大型的模型,这意味着在同一个场景下只会加载有限的元素。

import QtQuick 2.0

Rectangle {
    width: 80
    height: 300
    color: "white"
    ListView {
        anchors.fill: parent
        anchors.margins: 20
        clip: true
        model: 100
        delegate: numberDelegate
        spacing: 5
    }
    Component {
        id: numberDelegate
        Rectangle {
            width: 40
            height: 40
            color: "lightGreen"
            Text {
                anchors.centerIn: parent
                font.pixelSize: 10
                text: index
            }
        }
    }
}

如果模型包含的数据比屏幕上显示的更多,ListView元素只会显示部分的链表内容。然后由于QtQuick的默认行为导致的问题,列表视图不会限制被显示的代理项(delegates)只在限制区域内显示。这意味着代理项可以在列表视图外显示,用户可以看见在列表视图外动态的创建和销毁这些代理项(delegates)。为了防止这个问题,ListView通过设置clip属性为true,来激活裁剪功能。

代理:

当使用模型与视图来自定义用户界面时,代理在创建显示时扮演了大量的角色。在模型中的每个元素通过代理来实现可视化,用户真实可见的是这些代理元素。

每个代理访问到索引号或者绑定的属性,一些是来自数据模型,一些来自视图。来自模型的数据将会通过属性传递到代理。来自视图的数据将会通过属性传递视图中与代理相关的状态信息。

4、画布元素

    画布元素(canvas element)的基本思想是使用一个2D对象来渲染路径。这个2D对象包括了必要的绘图函数,画布元素(canvas element)充当绘制画布。2D对象支持画笔,填充,渐变,文本和绘制路径创建命令。

import QtQuick 2.0

Canvas {
id: root
width: 200; height: 200     // canvas size
// handler to override for drawing

onPaint: {
    var ctx = getContext("2d") // get context to draw with
                               // setup the stroke
    ctx.lineWidth = 4
    ctx.strokeStyle = "blue"  
 
    ctx.fillStyle = "steelblue" // setup the fill

    ctx.beginPath()     // begin a new path to draw

    ctx.moveTo(50,50)   // top-left start point
    ctx.lineTo(150,50)  // upper line
    ctx.lineTo(150,150) // right line
    ctx.lineTo(50,150)  // bottom line

    ctx.closePath() // left line through path closing

    ctx.fill()      // fill using fill style

    ctx.stroke()    // stroke using line width and stroke style
    }
}

典型绘制命令调用如下:
1. 装载画笔或者填充模式
2. 创建绘制路径
3. 使用画笔或者填充绘制路径

onPaint: {
    var ctx = getContext("2d")

    ctx.strokeStyle = "red"  // setup the stroke

    ctx.beginPath()  // create a path
    ctx.moveTo(50,50)
    ctx.lineTo(150,50)

    ctx.stroke()  // stroke path
}

便捷的接口(Convenient API):
在绘制矩形时,我们提供了一个便捷的接口,而不需要调用stroke或者fill来完成。

import QtQuick 2.0

Canvas {
    id: root
    width: 120; height: 120

    onPaint: {
    var ctx = getContext("2d")
    ctx.fillStyle = 'green'
    ctx.strokeStyle = "blue"
    ctx.lineWidth = 4
    ctx.fillRect(20, 20, 80, 80) // draw a filles rectangle
    ctx.clearRect(30,30, 60, 60) // cut our an inner rectangle
    // stroke a border from top-left to
    // inner center of the larger rectangle
    ctx.strokeRect(20,20, 40, 40)
    }
}

渐变(Gradients)
画布中可以使用颜色填充也可以使用渐变或者图像来填充。

onPaint: {
    var ctx = getContext("2d")
    var gradient = ctx.createLinearGradient(100,0,100,200)
    gradient.addColorStop(0, "blue")
    gradient.addColorStop(0.5, "lightsteelblue")
    ctx.fillStyle = gradient
    ctx.fillRect(50,50,100,100)
}

阴影(Shadows)

2D对象的路径可以使用阴影增强显示效果。阴影是一个区域的轮廓线使用偏移量,颜色和模糊来实现的。所以你需要指定一个阴影颜色(shadowColor),阴影X轴偏移值(shadowOffsetX),阴影Y轴偏移值(shadowOffsetY)和阴影模糊
(shadowBlur)。这些参数的定义都使用2D context来定义。2D context是唯一的绘制操作接口。
阴影也可以用来创建发光的效果。在下面的例子中我们使用白色的光创建了一个“Earth”的文本。在一个黑色的背景上可以有更加好的显示效果。

首先我们绘制黑色背景:
// setup a dark background
ctx.strokeStyle = "#333"
ctx.fillRect(0,0,canvas.width,canvas.height);
然后定义我们的阴影配置:
ctx.shadowColor = "blue";
ctx.shadowOffsetX = 2;
ctx.shadowOffsetY = 2;
// next line crashes
// ctx.shadowBlur = 10;
最后我们使用加粗的,80像素宽度的Ubuntu字体来绘制“Earth”文本:
ctx.font = 'Bold 80px Ubuntu';
ctx.fillStyle = "#33a9ff";
ctx.fillText("Earth",30,180);

图片(Images)
QML画布支持多种资源的图片绘制。在画布中使用一个图片需要先加载图片资源。
在我们的例子中我们使用Component.onCompleted操作来加载图片。

onPaint: {
    var ctx = getContext("2d")
    ctx.drawImage('assets/ball.png', 10, 10) // draw an image
    // store current context setup
    ctx.save()
    ctx.strokeStyle = 'red'
    // create a triangle as clip region
    ctx.beginPath()
    ctx.moveTo(10,10)
    ctx.lineTo(55,10)
    ctx.lineTo(35,55)
    ctx.closePath()
    // translate coordinate system
    ctx.translate(100,0)
    ctx.clip() // create clip from triangle path
    // draw image with clip applied
    ctx.drawImage('assets/ball.png', 10, 10)
    // draw stroke around path
    ctx.stroke()
    // restore previous setup
    ctx.restore()
}
Component.onCompleted: {
    loadImage("assets/ball.png")
}

转换(Transformation)
画布有多种方式来转换坐标系。这些操作非常类似于QML元素的转换。你可以通过缩放(scale),旋转(rotate),translate(移动)来转换坐标系。与QML元素的转换不同的是,转换原点通常就是画布原点。

import QtQuick 2.0
Canvas {
    id: root
    width: 240; height: 120
    onPaint: {
        var ctx = getContext("2d")
        ctx.strokeStyle = "blue"
        ctx.lineWidth = 4
        ctx.beginPath()
        ctx.rect(-20, -20, 40, 40)
        ctx.translate(120,60)
        ctx.stroke()
        // draw path now rotated
        ctx.strokeStyle = "green"
        ctx.rotate(Math.PI/4)
        ctx.stroke()
    }
}

 

5、粒子模拟

6、着色器效果

7、多媒体

8、网络

9、存储

10、动态QML

11、javaScript

12、Qt and C++

13、C++扩展QML

14、Other

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值