QT开发(五十三)———QML基本元素

QT开发(五十三)———QML基本元素

一、基本可视化项

可视元素具有几何坐标,会在屏幕上占据一块显示区域。

Item             基本的项元素,所有可视化项都继承Item

Rectangle        基本的可视化矩形元素

Gradient         定义一个两种颜色的渐变过程

GradientStop     定义个颜色,被Gradient使用

Image         在场景中使用位图

BorderImage     (特殊的项) 定义一张图片并当做边界

AnimatedImage    为播放动画存储一系列的帧

Text        在场景中使用文本

TextInput       显示可编辑为文本

IntValidatorint     验证器

DoubleValidator     double 验证器

RegExpValidator     验证字符串正则表达式

TextEdit    显示多行可编辑文本

1、Item

Item是所有可视元素中最基本的一个,是所有其它可视元素的父元素,所有其它可视元素都继承Item。Item本身没有任何绘制,作用是定义所有可视元素的通用属性。


分组


属性


几何


x和y用于定义元素左上角的坐标,width和height则定义了元素的范围。z定义了元素上下的层叠关系。


布局


anchors(具有 left、right、top、bottom、vertical 和 horizontal center 等属性)用于定位元素相对于其它元素的margins的位置。


键盘处理


Key和KeyNavigation属性用于控制键盘;focus属性则用于启用键盘处理,也就是获取焦点。


变形


提供scale和rotate变形以及更一般的针对 x、y、z 坐标值变换以及transformOrigin点的transform属性列表。


可视化


opacity属性用于控制透明度;visible属性用于控制显示/隐藏元素;clip属性用于剪切元素;smooth属性用于增强渲染质量。


状态定义


提供一个由状态组成的列表states和当前状态state属性;同时还有一个transitions列表,用于设置状态切换时的动画效果。

除了定义通用属性,Item另外一个重要作用是作为其它可视元素的容器。

2、Rectangle

Rectangle继承了Item,并在Item的基础之上增加了填充色属性、边框相关的属性。为了定义圆角矩形,Rectangle还有一个radius属性。下面的代码定义了一个宽150像素、高100像素,浅金属蓝填充,红色4像素的边框的矩形。

Rectangle
{
    id: rect
    width: 150
    height: 100
    color: "lightsteelblue"
    border
    {
        color: "#FF0000"
        width: 4
    }
    radius: 8
}

QML中的颜色值可以使用颜色名字,也可以使用#十六进制的形式。

Rectangle除了color属性外,还有一个gradient属性,用于定义使用渐变色填充。

Rectangle
{
    width: 150
    height: 100
    gradient: Gradient
    {
        GradientStop { position: 0.0; color: "red" }
        GradientStop { position: 0.33; color: "yellow" }
        GradientStop { position: 1.0; color: "green" }
    }
    border.color: "slategray"
}

gradient要求一个Gradient对象,Gradient对象需要一个GradientStop的列表。所谓渐变,就是指定在某个位置必须是某种颜色,中间的过渡色则由计算而得。    GradientStop对象就是用于指定某个位置的颜色,需要两个属性:position和color。前者是一个 0.0 到 1.0 的浮点数,说明y轴方向的位置,例如元素的最顶部是0.0,最底部是1.0,介于最顶和最底之间的位置可以用一个浮点数表示,也就是一个比例;后者是position位置的颜色值。GradientStop { position: 0.33; color: "yellow" }说明在从上往下三分之一处是黄色。

Rectangle必须同时指定(显式地或隐式地)宽和高,否则不能在屏幕上显示出来。

3、Text

Text元素最重要的属性当然就是text属性。这个属性类型是string。Text元素会根据文本和字体计算自己的初始宽度和高度。字体则可以通过字体属性组设置(例如font.family、font.pixelSize等)。如果要设置文本颜色,只需要设置color属性。

Text元素中的文本可以使用horizontalAlignment和verticalAlignment属性指定对齐方式。为了进一步增强文本渲染,可以使用style和styleColor两个属性。这两个属性允许我们指定文本的显示样式和样式的颜色。对于较长的文本,通常会选择在文本末尾使用 … ,elide属性允许指定 … 的显示位置。通过wrapMode属性可以指定换行模式。

Text
{
    width: 160
    height: 100
    text: "A very very long text"
    elide: Text.ElideRight
    style: Text.Sunken
    styleColor: ‘#FF4444‘
    verticalAlignment: Text.AlignTop
    font
    {
        pixelSize: 24
    }
}

Text元素的文本省略号位置在一行文本的右侧;具有一个#FF4444颜色的样式Sunken。Text元素的作用是显示文本,不会显示文本的任何背景。

4、Image

Image元素则用于显示图像。QML支持的图像格式有PNG、JPG、GIF 和 BMP 等。可以直接给source属性一个URL来自动从网络加载图片,可以通过fillMode属性设置改变大小的行为。

URL可以是本地路径,可以是网络路径。如果一个URL是网络的,QML 会自动从URL网络地址加载对应的资源。

Image
{
    x: 0;
    y: 0
    width: 97
    height: 120
    source: "http://ucenter.51cto.com/avatar.php?uid=9281927&size=middle"
    fillMode: Image.PreserveAspectCrop
    clip: true
}

Image.PreserveAspectCrop是等比例切割,需要同时设置clip属性,避免所要渲染的对象超出元素范围。

5、TextInput

TextInput是单行的文本输入框,支持验证器、输入掩码和显示模式等

import QtQuick 2.0
 
Rectangle {
    width: 200
    height: 80
    color: "blue"
 
    TextInput
    {
        id: input1
        x: 8; y: 8
        width: 96; height: 20
        focus: true
        text: "Text Input 1"
        KeyNavigation.tab: input2
    }
    TextInput
    {
        id: input2
        x: 8; y: 36
        width: 96; height: 20
        text: "Text Input 2"
        KeyNavigation.tab: input1
    }
}

有两个TextInput,用户可以通过点击输入框改变焦点。如果想支持键盘导航,可以添加KeyNavigation附加属性。KeyNavigation是一个附加属性。当用户点击了指定的按键时,属性指定的组件就会获得焦点。普通的属性隶属于类型;附加属性一般用于修饰或补充目标类型。KeyNavigation.tab并不是TextInput的普通属性,是用来说明TextInput的一种特征。附加属性的一般语法是类型.属性名,类型就是KeyNavigation,属性名就是tab。

6、TextEdit

TextEdit是多行的文本编辑组件

import QtQuick 2.0
 
Rectangle {
    width: 200
    height: 80
    color: "blue"
 
    TextEdit
    {
        id: edit1
        x: 8; y: 8
        width: 96; height: 20
        focus: true
        text: "Text Edit 1"
        KeyNavigation.tab: edit2
    }
    TextEdit
    {
        id: edit2
        x: 8; y: 36
        width: 96; height: 20
        text: "Text Edit 2"
        KeyNavigation.tab: edit1
    }
}

7、IntValidator

int 型验证器,和输入框结合后就是只能输入整型数据。

import QtQuick 2.0
 
TextInput
{
    IntValidator{id: intval; bottom: 10; top: 100;}
    width: 100; height: 20;
    text: "";
    validator: intval;
}

8、BorderImage

BorderImage将一张图片分为9部分,当图片进行缩放的时候

A.1 3 7 9位置的都不会进行缩放

B. 2 8将根据属性horzontalTileMode 进行缩放

C.4 6 将根据属性verticalTileMode 进行缩放

D.5 将根据属性horzontalTileMode 和 verticalTileMode 进行缩放

import QtQuick 2.0
 
BorderImage 
{
    width: 180; height: 180
    border { left: 30; top: 30; right: 30; bottom: 30 }
    horizontalTileMode: BorderImage.Stretch
    verticalTileMode: BorderImage.Stretch
    source: "http://ucenter.51cto.com/avatar.php?uid=9281927&size=middle"
}

9、DoubleValidator

DoubleValidator 只能输入浮点数

TextInput
{
    DoubleValidator
    {
        id: intval
        decimals: 4
        bottom: 10
        top: 100
        notation: DoubleValidator.StandardNotation
    }
    width: 100; height: 20;
    text: "";
    validator: intval;
}

10、RegExpValidator

RegExpValidator使用正则表达式

TextInput
{
    // 使用一个正则表达式来控制输入的字符串
    // /^[a-zA-Z]{1}[0-1]{0,2}[a-z]{1,3}$/ 表示 开始位置必须是一个大写或小写字母
    // 接下来是0~2个的数字而且是0或1,在接下来是1~3个的小写字母
    RegExpValidator{id: intval; regExp:/^[a-zA-Z]{1}[0-1]{0,2}[a-z]{1,3}$/;}
    width: 100; height: 20;
    text: "";
    validator: intval;
}

11、AnimatedImage

AnimatedImage 主要用于播放gif图片

import QtQuick 2.0
 
Rectangle
{
    width: animation.width; height: animation.height + 8
    AnimatedImage
    {
        id: animation
        source: "animation.gif"
    }
    Rectangle
    {
        property int frames: animation.frameCount
        width: 4; height: 8
        x: (animation.width - width) * animation.currentFrame / frames
        y: animation.height
        color: "red"
    }
}

二、基本的交互项

不可视元素(例如Timer)通常提供一种作用于可视元素的功能。

MouseArea    鼠标句柄交互

FocusScope      键盘焦点句柄

Flickable       提供一种浏览整张图片的一部分的效果

Flipable提供一个平面,可以进行翻转看前面或后面

1、MouseArea

MouseArea用于用户交互,是一个不可见的矩形区域,用于捕获鼠标事件。通常会将MouseArea元素与一个可视元素结合起来使用,以便可视元素能够与用户交互。

Rectangle
{
    id: rect
    x: 0;
    y: 0
    width: 150;
    height: 100
    color: "red"
    MouseArea
    {
        anchors.fill:parent
        onClicked:
        {
            Qt.quit();
        }
    }
}

MouseArea将可视化展示与用户输入控制解耦,可以显示一个较小的元素,但有一个很大的可交互区域,以便在界面显示与用户交互之间找到一个平衡(如果在移动设备上,较小的区域非常不容易被用户成功点击。苹果公司要求界面的交互部分最少要有 40 像素以上,才能够很容易被手指点中)。

2、FocusScope

Widget.qml文件:

import QtQuick 2.0
 
FocusScope
{
    id: scope
    property alias color: rectangle.color
    x: rectangle.x; y: rectangle.y
    width: rectangle.width; height: rectangle.height
    Rectangle
    {
        id: rectangle
        anchors.centerIn: parent
        color: "lightsteelblue"
        width: 175; height: 30
        radius: 10; antialiasing: true
        Text { id: label; anchors.centerIn: parent }
        focus: true
        Keys.onPressed:
        {
            if (event.key == Qt.Key_A)
                label.text = ‘Key A was pressed‘
            else if (event.key == Qt.Key_B)
                label.text = ‘Key B was pressed‘
            else if (event.key == Qt.Key_C)
                label.text = ‘Key C was pressed‘
        }
    }
    MouseArea
    {
        anchors.fill: parent;
        onClicked: { scope.focus = true }
    }
}

使用Widget组件:

import QtQuick 2.0
 
Rectangle
{
    id: widget
    width: 240; height: 150
    color:"white";
 
    Column
    {
        anchors.centerIn: parent; spacing: 15
        Widget
        {
            color: "lightblue"
        }
        Widget
        {
            focus:true
            color: "palegreen"
        }
    }
}

3、Flickable

QML中提供了一个Flickable元素,可以将其子项目设置在一个可以拖曳和弹动的界面上,使得子项目的视图可以滚动。Flickable不会自动剪裁它的内容,如果不是将它用作全屏项目,可以将clip属性设置为true来隐藏超出区域的内容。

import QtQuick 2.0
 
Flickable
{
    width: 200; height: 200
    contentWidth: image.width
    contentHeight: image.height
    //interactive: false    //禁止拖动弹动功能
    Image
    {
        id: image
        source: "http://ucenter.51cto.com/avatar.php?uid=9281927&size=middle"
    }
}

4、Flipable

Flipable是一个可以明显在其正面和反面之间进行翻转的项目,同时使用Rotation、State和Transition等元素来产生翻转效果。front和back分别用来保存要显示在Flipable项目的正面和反面的项目。Flipable有一个flipped布尔值属性,每当在Flipable中的MouseArea上单击鼠标时都会切换该属性的值。当flipped为true时,项目变为back状态,在这个状态,Rotation的angle属性改变为180°来产生一个翻转效果。当flipped为false时,项目恢复到默认状态,angle的值为 0。

import QtQuick 2.6
 
Flipable
{
    id: flipable
    width: 240; height:240
    property bool flipped: false
    //正面、反面图片资源
    front: Image{source: "1.jpg"; anchors.centerIn: parent}
    back: Image{source: "2.jpg"; anchors.centerIn: parent}
    transform: Rotation
    {
        id: rotation
        origin.x: flipable.width / 2
        origin.y: flipable.height / 2
        axis.x: 0; axis.y: 1; axis.z: 0
        angle: 0
    }
    states: State
    {
        name: "back"
        PropertyChanges { target: rotation; angle: 180 } //翻转效果
        when: flipable.flipped
    }
    transitions: Transition
    {
        NumberAnimation {target: rotation; property: "angle"; duration: 800}
    }
    MouseArea
    {
        anchors.fill: parent
        onClicked: flipable.flipped = !flipable.flipped
    }
}

三、状态

State               定义一个配置对象和属性的集合

PropertyChanges     使用一个State描述属性的改变

StateGroup          包含一个状态集合和状态变换

ParentChange        重新定义父集,也就是换个父节点

AnchorChanges       在一个状态中改变anchors

1、State

import QtQuick 2.0
 
Rectangle
{
    id: rect
    width: 100; height: 100
    color: "black"
    MouseArea
    {
        id: mouseArea
        anchors.fill: parent
        onClicked: rect.state == ‘clicked‘ ? rect.state = "" : rect.state = ‘clicked‘;
    }
    // 设置状态
    states:
    [
        State
        {
            name: "clicked"
            PropertyChanges { target: rect; color: "red" }
        }
    ]
}

2、PropertyChanges

import QtQuick 2.0
 
Text
{
    id: myText
    width: 100; height: 100
    text: "Hello"
    color: "blue"
    states: State
    {
        name: "myState"
        PropertyChanges
        {
            target: myText
            text: "Goodbye"
            color: "red"
        }
    }
    MouseArea
    {
        anchors.fill: parent;
        onClicked: myText.state = ‘myState‘
    }
}

3、ParentChange

把指定的item换一个item父节点

import QtQuick 2.0
 
Item
{
    width: 200; height: 100
    Rectangle
    {
        id: redRect
        width: 100; height: 100
        color: "red"
    }
    Rectangle
    {
        id: blueRect
        x: redRect.width
        width: 50; height: 50
        color: "blue"
        states: State
        {
            name: "reparented"
            // 改变父节点
            ParentChange
            {
                target: blueRect;
                parent: redRect;
                x: 10; y: 10
            }
        }
        MouseArea
        {
            anchors.fill: parent;
            onClicked: blueRect.state = "reparented"
        }
    }
}

4、AnchorChanges

import QtQuick 2.0
 
Rectangle
{
    id: window
    width: 120; height: 120
    color: "black"
    Rectangle
    {
        id: myRect;
        width: 50;
        height: 50;
        color: "red"
    }
    states: State
    {
        name: "reanchored"
        AnchorChanges
        {
            target: myRect
            anchors.top: window.top
            anchors.bottom: window.bottom
        }
        PropertyChanges
        {
            target: myRect
            anchors.topMargin: 10
            anchors.bottomMargin: 10
        }
    }
    // 鼠标事件
    MouseArea
    {
        anchors.fill: parent;
        onClicked: window.state = "reanchored"
    }
}

四、动画和变换

Behavior             默认的属性变换动画

SequentialAnimation  对定义的动画串行播放

ParallelAnimation    对定义的动画并行播放

PropertyAnimation    属性变换动画

NumberAnimation      对实数类型属性进行的动画

Vector3dAnimation    对QVector3d进行的属性

ColorAnimation       颜色进行的变换动画

RotationAnimation    对旋转进行的变换动画

ParentAnimation      对父节点进行变换的动画,改变绑定的父节点

AnchorAnimation      对anchor 进行改变的动画

PauseAnimation       延迟处理

SmoothedAnimation    允许属性平滑的过度

SpringAnimation      一种加速的效果

PropertyAction     允许在动画过程中对属性的直接改变

ScriptAction     允许动画过程中调用脚本

Transition     在状态变换中加入动作变化

1、Behavior

一个特定的属性值改变时要应用一个动画,可以使用一个Behavior为一个属性改变指定一个默认的动画。

import QtQuick 2.0
 
Rectangle
{
    id: rect
    width: 100; height: 100
    color: "red"
    // 针对宽度的动画
    Behavior on width
    {
        NumberAnimation { duration: 1000 }
    }
 
    MouseArea
    {
        anchors.fill: parent
        onClicked: rect.width = 50
    }
}

2、SequentialAnimation

串行播放多个动画

Rectangle
{
    id: rect1
    width: 500; height: 500
    Rectangle
    {
        id: rect;
        color: "red"
        width: 100; height: 100
        // 串行播放多个动画,先横向移动,在纵向移动
        SequentialAnimation
        {
            running: true;
            NumberAnimation {target:rect; properties:"x"; to: 50; duration: 1000 }
            NumberAnimation {target:rect; properties:"y"; to: 50; duration: 1000 }
        }
    }
}

3、ParallelAnimation

import QtQuick 2.0
 
Rectangle
{
    id: rect1
    width: 500; height: 500
    Rectangle
    {
        id: rect;
        color: "red"
        width: 100; height: 100
        // 并行播放动画,同时横向和纵向移动
        ParallelAnimation
        {
            running: true;
            NumberAnimation {target:rect; properties:"x"; to: 50; duration: 1000 }
            NumberAnimation {target:rect; properties:"y"; to: 50; duration: 1000 }
        }
    }
}

4、PropertyAnimation

一个动画被应用为属性值源(property value source)。

import QtQuick 2.0
 
Rectangle
{
    id: rect
    width: 100; height: 100
    color: "red"
    states: State
    {
        name: "moved"
        PropertyChanges
        {
            target: rect; x: 50
        }
    }
    transitions: Transition
    {
        // 属性动画 当属性 x或y发生变化的时候,就播放这样一个动画
        PropertyAnimation { properties: "x,y"; easing.type: Easing.InOutQuad }
    }
    MouseArea
    {
        anchors.fill: parent;
        onClicked: rect.state = "moved";
    }
}

5、NumberAnimation

import QtQuick 2.0
 
Rectangle
{
    width: 100; height: 100
    color: "red"
    // 对当前item的x进行移动,目标移动到x = 50
    NumberAnimation on x { to: 50; duration: 1000 }
}

6、ColorAnimation

颜色过度

import QtQuick 2.0
 
Rectangle
{
    width: 100; height: 100
    color: "red"
    ColorAnimation on color { to: "yellow"; duration: 1000 }
}

7、RotationAnimation

import QtQuick 2.0
 
Item
{
    width: 300; height: 300
    Rectangle
    {
        id: rect
        width: 150; height: 100; anchors.centerIn: parent
        color: "red"
        smooth: true
        states: State
        {
            name: "rotated";
            PropertyChanges { target: rect; rotation: 180}
        }
        transitions: Transition
        {
            RotationAnimation
            {
                duration: 1000
                direction: RotationAnimation.Counterclockwise
            }
        }
    }
    MouseArea
    {
        anchors.fill: parent;
        onClicked: rect.state = "rotated"
    }
}

8、ParentAnimation

一个切换父节点的动画,平滑的过度

import QtQuick 2.0
 
Item
{
    width: 200; height: 100
    Rectangle
    {
        id: redRect
        width: 100; height: 100
        color: "red"
    }
 
    Rectangle
    {
        id: blueRect
        x: redRect.width
        width: 50; height: 50
        color: "blue"
        states: State
        {
            name: "reparented"
            ParentChange
            {
                target: blueRect
                parent: redRect
                x: 10; y: 10
            }
        }
        transitions: Transition
        {
            ParentAnimation
            {
                NumberAnimation { properties: "x,y"; duration: 1000 }
            }
        }
        MouseArea
        {
            anchors.fill: parent
            onClicked: blueRect.state = "reparented"
        }
    }
}

9、AnchorAnimation

import QtQuick 2.0
 
Item
{
    id: container
    width: 200; height: 200
    Rectangle
    {
        id: myRect
        width: 100; height: 100
        color: "red"
    }
    states: State
    {
        name: "reanchored"
        AnchorChanges { target: myRect; anchors.right: container.right }
    }
    transitions: Transition
    {
        AnchorAnimation { duration: 1000 }
    }
    // 当控件加载完成后
    Component.onCompleted: container.state = "reanchored"
}

10、PauseAnimation

延迟效果

import QtQuick 2.0
 
Item
{
    id: container
    width: 200; height: 200
    Rectangle
    {
        id: myRect
        width: 100; height: 100
        color: "red"
        SequentialAnimation
        {
            running: true;
            NumberAnimation {target: myRect;to: 50; duration: 1000; properties: "x"; }
            PauseAnimation { duration: 5000 } // 延迟100毫秒
            NumberAnimation {target: myRect; to: 50; duration: 1000; properties: "y"; }
        }
    }
}

11、SmoothedAnimation

平滑过度

import QtQuick 2.0
 
Rectangle
{
    width: 800; height: 600
    color: "blue"
    Rectangle
    {
        width: 60; height: 60
        x: rect1.x - 5; y: rect1.y - 5
        color: "green"
        Behavior on x { SmoothedAnimation { velocity: 200 } }
        Behavior on y { SmoothedAnimation { velocity: 200 } }
    }
    Rectangle
    {
        id: rect1
        width: 50; height: 50
        color: "red"
    }
    focus: true
    Keys.onRightPressed: rect1.x = rect1.x + 100
    Keys.onLeftPressed: rect1.x = rect1.x - 100
    Keys.onUpPressed: rect1.y = rect1.y - 100
    Keys.onDownPressed: rect1.y = rect1.y + 100
}

12、SpringAnimation

平滑的过度过程,在动画结束的时候有种弹性的效果

import QtQuick 2.0
 
Item
{
    width: 300; height: 300
    Rectangle
    {
        id: rect
        width: 50; height: 50
        color: "red"
        Behavior on x { SpringAnimation { spring: 2; damping: 0.2 } }
        Behavior on y { SpringAnimation { spring: 2; damping: 0.2 } }
    }
    MouseArea
    {
        anchors.fill: parent
        onClicked:
        {
            rect.x = mouse.x - rect.width/2
            rect.y = mouse.y - rect.height/2
        }
    }
}

13、PropertyAction

主要是在动画过程中直接的改变一个属性

import QtQuick 2.0
 
transitions:Transition
{
    ...
    PropertyAction { target: theImage; property: "smooth"; value: true }
    ...
}

14、ScriptAction

import QtQuick 2.0
 
SequentialAnimation
{
    NumberAnimation { ... }
    ScriptAction { script: doSomething(); }
    NumberAnimation { ... }
}

15、Transition

import QtQuick 2.0
 
Rectangle
{
    id: rect
    width: 100; height: 100
    color: "red"
    MouseArea
    {
        id: mouseArea
        anchors.fill: parent
    }
    states: State
    {
        name: "moved"; when: mouseArea.pressed
        PropertyChanges { target: rect; x: 50; y: 50 }
    }
    transitions: Transition
    {
        NumberAnimation { properties: "x,y"; easing.type: Easing.InOutQuad }
    }
}

五、数据项

Binding         在创建的时候绑定一些数据到一些属性

ListModel       定义链表数据

ListElement     定义ListModel的一个数据项

VisualItemModel  包含可视化项(visual items)到一个view中,相当是一个容器

VisualDataModel  包含一个model和一个delegate,model包含需要的数据,delegate设计显示的项的信息

Package          把VisualDataModel共享给多个view

XmlListModel     特殊的一个模式使用XPath表达式,使用xml来设置元素

XmlRole          XmlListModel的一个特殊的角色

1、Binding

import QtQuick 2.0
 
Item
{
    width: 300; height: 300
    Text {id: app; text: "xxxfa"}
    TextEdit
    { id: myTextField;
        text: "Please type here..."
    }
    // 把myTextField和app的enteredText属性进行绑定
    Binding
    {
        target: app;
        property: "enteredText";
        value: myTextField.text
    }
}

2、ListModel

import QtQuick 2.0
 
Rectangle
{
    width: 200; height: 200
    ListModel
    {
        id: fruitModel
        ListElement
        {
            name: "Apple"
            cost: 2.45
        }
        ListElement
        {
            name: "Orange"
            cost: 3.25
        }
        ListElement
        {
            name: "Banana"
            cost: 1.95
        }
    }
    Component
    {
        id: fruitDelegate
        Row
        {
            spacing: 10
            Text { text: name }
            Text { text: ‘$‘ + cost }
        }
    }
    ListView
    {
        anchors.fill: parent
        model: fruitModel
        delegate: fruitDelegate
    }
}

3、VisualItemModel

import QtQuick 2.0
 
Rectangle
{
    width: 100; height: 100;
    VisualItemModel
    {
        id: itemModel
        Rectangle { height: 30; width: 80; color: "red" }
        Rectangle { height: 30; width: 80; color: "green" }
        Rectangle { height: 30; width: 80; color: "blue" }
    }
    ListView
    {
        anchors.fill: parent
        model: itemModel
    }
}

4、VisualDataModel

import QtQuick 2.0
 
Rectangle
{
    width: 200; height: 100
    VisualDataModel
    {
        id: visualModel
        model: ListModel
        {
            ListElement { name: "Apple" }
            ListElement { name: "Orange" }
        }
        delegate: Rectangle
        {
            height: 25
            width: 100
            Text { text: "Name: " + name}
        }
    }
    ListView
    {
        anchors.fill: parent
        model: visualModel
    }
}

六、视图

ListView      提供一个链表显示模型试图

GridView      提供一个网格显示模型试图

PathView      提供一个内容沿着路径来显示的模型

Path          定义一个PathView使用的轨迹

PathLine      定义一个线性的轨迹

PathQuad      定义一个二次贝塞尔曲线的轨迹

PathCubic     定义一个三次贝塞尔曲线的轨迹

PathAttribute 允许绑定一个属性上,具体看例子

PathPercent   修改item分配的轨迹 不是很明了其中的意思

WebView       允许添加网页内容到一个canvas上

1、GridView

import QtQuick 2.0
 
Rectangle
{
    width: 200; height: 400;
    ListModel
    {
        id: fruitModel
        ListElement
        {
            name: "Apple"
            cost: 2.45
        }
 
        ListElement
        {
            name: "Orange"
            cost: 3.25
        }
 
        ListElement
        {
            name: "Banana"
            cost: 1.95
        }
    }
 
    GridView
    {
        anchors.fill: parent
        model: fruitModel
        delegate: Column
        {
            Text {text:"name" + name}
            Text {text:"cost"+ cost}
        }
    }
}

2、PathView

import QtQuick 2.0
 
Rectangle
{
    width: 200; height: 400;
    ListModel
    {
        id: fruitModel
        ListElement
        {
            name: "Apple"
            cost: 2.45
        }
 
        ListElement
        {
            name: "Orange"
            cost: 3.25
        }
 
        ListElement
        {
            name: "Banana"
            cost: 1.95
        }
    }
    PathView
    {
        anchors.fill: parent
        model: fruitModel
        delegate: Column
        {
            Text {text:"name" + name}
            Text {text:"cost"+ cost}
        }
 
        path:Path
        {
            startX: 120; startY: 100
            PathQuad { x: 120; y: 25; controlX: 260; controlY: 75 }
            PathQuad { x: 120; y: 100; controlX: -20; controlY: 75 }
        }
    }
}

3、PathLine

import QtQuick 2.0
 
Rectangle
{
    width: 200; height: 400;
    ListModel
    {
        id: fruitModel
        ListElement
        {
            name: "Apple"
            cost: 2.45
        }
        ListElement
        {
            name: "Orange"
            cost: 3.25
        }
        ListElement
        {
            name: "Banana"
            cost: 1.95
        }
    }
    PathView
    {
        anchors.fill: parent
        model: fruitModel
        delegate: Column
        {
            Text {text:"name" + name}
            Text {text:"cost"+ cost}
        }
        path:Path
        {
            startX: 150; startY: 120
            PathLine { x: 200; y: 80; }
            PathLine { x: 100; y: 80; }
            PathLine { x: 150; y: 120; }
         }
    }
}

4、PathAttribute

import QtQuick 2.0
 
Rectangle
{
    width: 200; height: 400;
    ListModel
    {
        id: fruitModel
        ListElement
        {
            name: "Apple"
            cost: 2.45
        }
        ListElement
        {
            name: "Orange"
            cost: 3.25
        }
        ListElement
        {
            name: "Banana"
            cost: 1.95
        }
    }
    PathView
    {
        anchors.fill: parent
        model: fruitModel
        delegate:
        Item
        {
            id: delitem;
            width: 80; height: 80;
            Column
            {
                Rectangle
                {
                    width: 40; height: 40;
                    scale: delitem.scale;
                    color: "red"
                }
                Text {text:"name" + name}
                Text {text:"cost"+ cost}
            }
        }
        path: Path
        {
            startX: 120; startY: 100
            PathAttribute { name: "Scale"; value: 1.0 }
            PathQuad { x: 120; y: 25; controlX: 260; controlY: 75 }
            PathAttribute { name: "Scale"; value: 0.3 }
            PathQuad { x: 120; y: 100; controlX: -20; controlY: 75 }
        }
    }
}

5、WebView

import QtQuick 2.0
import QtWebKit 1.0
 
WebView
{
    url: "http://www.nokia.com"
    preferredWidth: 490
    preferredHeight: 400
    scale: 0.5
    smooth: false
}

七、定位器

Column     整理它的子列(纵)

Row        整理它的子行(横)

Grid   设置它的子到一个网格上

Flow   目的是不让他的子项重叠在一起

QML提供的多种用于定位的元素叫做定位器,包含在 QtQuick模块。QML定位器主要有Row、Column、Grid和Flow等。

1、Column

Column将子元素按照加入的顺序从上到下,在同一列排列出来。spacing属性用于定义子元素之间的间隔。

Main.qml文件:

import QtQuick 2.0
 
Rectangle
{
    id: root
    width: 120
    height: 120
    color: "blue"
    Column
    {
        id: row
        anchors.centerIn: parent
        spacing: 8
        Button
        {
            color:"red"
            width:60
            text:"hello"
        }
        Button
        {
            color:"green"
            width: 96
            text:"close"
        }
        Button
        {
            color:"gray"
            width:60
        }
    }
}

2、Row

Row将其子组件放置在一行的位置,既可以设置从左向右,也可以设置从右向左,取决于layoutDirection属性。spacing属性用于指定子组件之间的间隔。

Main.qml文件:

import QtQuick 2.0
 
Rectangle
{
    id: root
    width: 240
    height: 80
    color: "blue"
    Row
    {
        id: row
        anchors.centerIn: parent
        spacing: 8
        Button
        {
            color:"red"
            width:60
            text:"hello"
        }
        Button
        {
            color:"green"
            width: 96
            text:"close"
        }
        Button
        {
            color:"gray"
            width:60
        }
    }
}

3、Grid

Grid元素将其子元素排列为一个网格,需要制定rows和columns属性,也就是行和列的数值。如果二者有一个不显式设置,则另外一个会根据子元素的数目计算出来。如果设置为3行,一共放入6个元素,列数会自动计算为2。flow和layoutDirection属性则用来控制添加到网格的元素的顺序。Grid元素也有spacing属性。

Main.qml文件:

import QtQuick 2.0
 
Rectangle
{
    id: root
    width: 200
    height: 200
    color: "black"
    Grid
    {
        id: grid
        rows:2
        anchors.centerIn: parent
        spacing: 8
        Button
        {
            color:"red"
            width:60
            text:"hello"
        }
        Button
        {
            color:"green"
            width: 96
            text:"close"
        }
        Button
        {
            color:"gray"
            width:60
        }
    }
}

设定Grid的rows属性为2,添加3个子元素,columns属性会自动计算为2。

4、Flow

Flow定位器会将其子元素以流的形式显示出来。使用flow和layoutDirection两个属性来控制显示方式,可以从左向右横向布局,也可以从上向下纵向布局。添加到Flow里面的元素,当Flow的宽度或高度不足时,元素会自动换行。为了令Flow正确工作,需要指定其宽度或者高度。

Main.qml文件:

import QtQuick 2.0
 
Rectangle
{
    id: root
    width: 200
    height: 200
    color: "black"
    Flow
    {
        anchors.fill: parent
        anchors.margins: 20
        spacing: 8
        Button
        {
            color:"red"
            width:60
            text:"hello"
        }
        Button
        {
            color:"green"
            width: 80
            text:"close"
        }
        Button
        {
            color:"gray"
            width:60
        }
    }
}

三个按钮组件边长分别是60,80,60px,整个主窗口的宽是200px,Flow元素外边距 20px,因此Flow的宽度其实是 200px – 20px – 20px = 160px。Flow子元素间距为20px,两个按钮组件所占据的宽度就已经60px + 20px + 80px = 160px,3个则是160px + 20px + 60px = 240px > 200px,默认窗口大小一行只能显示两个按钮组件,第三个按钮组件自动换行。当拖动改变窗口大小时,可以观察Flow元素是如何工作的。如果拖动窗口宽度变长时,第三个按钮组件将会显示在第一行,如果拖动拖动窗口宽度变窄时,第二、三个按钮组件会换行到第二行、第三行。

5、Repeater

Repeater是一个结合定位器一起使用的元素。Repeater像一个for循环,能够遍历数据模型中的元素。

import QtQuick 2.0
 
Rectangle
{
    id: root
    width: 268
    height: 268
    color: "black"
    property variant colorArray: ["#00bde3", "#67c111", "#ea7025", "#ff0000"]
 
    Grid
    {
        anchors.fill: parent
        anchors.margins: 8
        spacing: 4
        Repeater
        {
            model: 16
            Rectangle
            {
                width: 60; height: 60
                property int colorIndex: Math.floor(Math.random()*4)
                color: root.colorArray[colorIndex]
                border.color: Qt.lighter(color)
                Text
                {
                    anchors.centerIn: parent
                    color: "black"
                    text: "Cell " + index
                }
            }
        }
    }
}

将Repeater同Grid一起使用,Repeater作为Grid的数据提供者。Repeater的model可以是任何能够接受的数据模型,并且只能重复基于Item的组件。重复生成16个定义的Rectangle元素。

Repeater会按照model属性定义的个数循环生成其子元素。每一次循环,Repeater都会创建一个矩形作为自己的子元素。新生成的矩形的颜色按照Math.floor(Math.random()*3)的算法计算而得。颜色选择算法会得到 0,1,2,4四者之一,用于选择数组colorArray中预定义的颜色。JavaScript是QtQuick 的核心部分,JavaScript标准函数都是可用的。

Repeater会为每一个子元素注入一个index属性,就是当前的循环索引,可以在子元素定义中直接使用index属性。

使用Repeater时,需要注意性能问题。处理很大的数据模型,或者需要动态获取数据时,Repeater代码会非常吃力,需要另外的实现。Repeater不适用于处理大量数据或者动态数据,仅适用于少量的静态数据的呈现。

八、实用项

Connections        明确连接信号和信号句柄

Component          封装QML items 想一个组件一样

Timer              提供时间触发器

QtObject           基本的元素只包含objectName属性

Qt                 qml全局Qt object提供使用的枚举和函数

WorkerScript       允许在QML使用线程

Loader             控制载入item或组件

Repeater           使用一个模型创建多个组件

SystemPalette      为Qt palettes提供一个通道

FontLoader         载入字体根据名字或URL

LayoutItem         允许声明UI元素插入到qtGraphicsView 布局中

1、Connections

import QtQuick 2.0
 
Rectangle
{
    width: 100; height: 100;
    MouseArea
    {
        id: area
        anchors.fill: parent;
    }
    Connections
    {
        target: area
        onClicked: { console.log(" ok");}
    }
}

2、Component

import QtQuick 2.0
 
Item
{
    width: 100; height: 100
    Component
    {
        id: redSquare
        Rectangle
        {
            color: "red"
            width: 10
            height: 10
        }
    }
    // 动态的载入一个组件
    Loader { sourceComponent: redSquare }
    Loader { sourceComponent: redSquare; x: 20 }
}

3、Timer

import QtQuick 2.0
 
Item
{
    width: 200; height: 40;
    Timer
    {
        interval: 500; running: true; repeat: true
        onTriggered: time.text = Date().toString() // 使用javascript获取系统时间
    }
    Text { id: time }
}

4、Repeater

import QtQuick 2.0
 
Row
{
    Repeater
    {
        model: 3
        Rectangle
        {
            width: 100; height: 40
            border.width: 1
            color: "yellow"
        }
    }
}

5、SystemPalette

Rectangle
{
    SystemPalette
    {
        id: myPalette;
        colorGroup: SystemPalette.Active
    }
    width: 640; height: 480
    color: myPalette.window
    Text
    {
        anchors.fill: parent
        text: "Hello!"; color: myPalette.windowText
    }
}

6、FontLoader

Column 
{
    FontLoader { id: fixedFont; name: "Courier" }
    FontLoader { id: webFont; source: "http://www.mysite.com/myfont.ttf" }
    Text { text: "Fixed-size font"; font.family: fixedFont.name }
    Text { text: "Fancy font"; font.family: webFont.name }
}

九、变换

Scale       分派item 缩放行为

Rotation    分派item 旋转行为

Translate   分派item 移动行为

1、Scale

import QtQuick 2.0
 
Rectangle
{
    width: 100; height: 100
    color: "blue"
    Rectangle
    {
        x: 50; y: 50;
        width: 20; height: 20;
        color: "red"
        transform: Scale { origin.x: 10; origin.y: 10; xScale: 3}
    }
}

2、Rotation

import QtQuick 2.0
 
Rectangle
{
    width: 100; height: 100
    color: "blue"
    // 绕位置25,25 旋转45度
    transform: Rotation { origin.x: 25; origin.y: 25; angle: 45}
}

3、Translate

import QtQuick 2.0
 
Row
{
    Rectangle
    {
        width: 100; height: 100
        color: "blue"
        // 沿y轴正方向移动20个像素
        transform: Translate { y: 20 }
    }
    Rectangle
    {
        width: 100; height: 100
        color: "red"
        // 沿y轴负方向移动20个像素
        transform: Translate { y: -20 }
    }
}

十、元素布局

除了定位器,QML 还提供了另外一种用于布局的机制:锚点(anchor)。锚点允许我们灵活地设置两个元素的相对位置,使两个元素之间形成一种类似于锚的关系,也就是两个元素之间形成一个固定点。锚点的行为类似于一种链接,它要比单纯地计算坐标改变更强。锚点描述的是相对位置,在使用锚点时,必须指定两个元素,声明其中一个元素相对于另外一个元素。锚点是Item元素的基本属性之一,因而适用于所有QML可视元素。

一个元素有6个主要的锚点的定位线:top、bottom、left、right、horizontalCenter和verticalCenter。对于Text元素,还有一个baseline锚点。每一个锚点定位线都可以结合一个偏移的数值。top、bottom、left和right称为外边框;horizontalCenter、verticalCenter和baseline称为偏移量。

import QtQuick 2.0
 
Rectangle {
    width: 200
    height: 200
    color: "blue"
    border.color: Qt.lighter(color)
 
    MouseArea
    {
        anchors.fill: parent
        drag.target: parent
    }
}

MouseArea组件是一个用于处理鼠标事件的组件。drag.target: parent说明拖动目标是parent,拖动对象是MouseArea的父组件,即Rectangle组件。anchors.fill设置内部蓝色矩形的锚点为填充(fill),填充的目的对象是parent;anchors.margins: 10表示填充边距是10px。虽然设置了矩形宽度为12px,但锚点的优先级要高于宽度属性设置,所以蓝色矩形的实际宽度是100px – 10px – 10px = 80px。

import QtQuick 2.0
 
Rectangle
{
    id: root
    width: 220
    height: 220
    color: "black"
 
    Rectangle
    {
        x: 10
        y: 10
        width: 100
        height: 100
        color:"blue"
        Rectangle
        {
            x:8
            y: 8
            width:60
            height:60
            color:"green"
            anchors.left: parent.left
            anchors.leftMargin: 8
            MouseArea
            {
                anchors.fill: parent
                drag.target: parent
            }
        }
    }
}

anchors.left设置内部绿色矩形的锚点为父组件的左边线(parent.left);左边距是8px。可以试着拖动绿色矩形,拖动绿色矩形时,绿色矩形只能沿着距离父组件蓝色矩形左边8px的位置上下移动。

anchors.left: parent.right设置锚点的左侧为父组件的右侧

anchors.top: parent.bottom设置锚点的上侧为父组件的底侧

anchors.topMargin: 4设置锚点的上侧边距为4

anchors.horizontalCenter: parent.horizontalCenter设置锚点的水平中心为父组件的水平中心

时间: 2024-10-22 08:05:06

QT开发(五十三)———QML基本元素的相关文章

QT开发(十三)——QT信号与槽机制

QT开发(十三)--QT信号与槽机制 一.QT消息模型 QT封装了具体操作系统的消息机制,遵循经典的GUI消息驱动事件模型. QT定义了与操作系统消息相关的自己的概念,即信号与槽. 信号signal是由操作系统产生的消息. 槽slot是程序中的消息处理函数. connect将系统消息绑定到消息处理函数. 信号到槽的连接必须发生在两个QT对象间. bool QObject::connect ( const QObject * sender, //发生对象 const char * signal,

Qt开发学习教程

Qt开发学习教程 一.Qt开发基础学习教程 本部分博客主要根据狄泰学院唐老师的<QT实验分析教程>创作,同时根据天山老妖自己的理解和网络搜集的资料及QT官方文档对部分知识点进行了扩展.本系列博客由天山老妖创作,发布于51CTO博客上.狄泰学院网站:http://course.dt4sw.com/ Qt开发基础学习教程目录如下: QT开发(一)--QT简介http://blog.51cto.com/9291927/1856911QT开发(二)--QT开发环境搭建http://blog.51cto

QT开发(五十四)———QML组件

QT开发(五十四)---QML组件 QML组件是由基本元素组合成的一个复杂的可重用的组合元素.QML 提供了多种方法来创建组件. 基于文件的组件将QML元素放置在一个单独的文件中,然后给文件一个名字,可以通过名字来使用组件.如果有一个文件名为Cell.qml,就可以在QML中使用Cell { - }形式.自定义组件的文件名的首字母必须大写. Cell.qml文件: import QtQuick 2.0   Item {     id: container     property alias c

QT开发(五十二)———QML语言

QT开发(五十二)---QML语言 QML是一种声明语言,用于描述程序界面.QML将用户界面分解成一块块小的元素,每一元素都由很多组件构成.QML定义了用户界面元素的外观和行为:更复杂的逻辑则可以结合JavaScript脚本实现. 一.QML基础语法 1.Import语句 QML代码中,import语句一般写在头几行,主要用途如下:     A.包含类型的全名空间     B.包含QML代码文件的目录     C.JavaScript代码文件 格式如下: import Namespace Ver

QT开发(五十五)———Qt Quick Controls

QT开发(五十五)---Qt Quick Controls 一.Qt Quick Controls基础 QT5.1发布了Qt Quick的一个全新模块:Qt Quick Controls.Qt Quick Controls模块提供了大量类似Qt Widgets模块的可重用组件. 为了开发基于Qt Quick Controls的程序,需要创建一个Qt Quick Application类型的应用程序,选择组件集的时候注意选择Qt Quick Controls. 二.Qt Quick Control

QT开发(五十一)——QtQuick基础

QT开发(五十一)--QtQuick基础 一.QtQuick简介 QT提供了两种独立的方法创建用户界面. QtQuick模块为创建流畅.鲜活的用户界面提供了一种标记语言.QtQuick模块适合需要动画元素的界面,以及应用程序主要运行在小屏幕和多点触控的设备上的场景. QtWidgets模块针对传统桌面提供了更多的支持,和目标平台做了更多的集成,无论目标平台是MacOSX.Windows.KDE.GNome.QtWidgets是一个非常高效的基于C++的类库,包含很多常见的用户界面组件,可以非常容

QT开发(六十三)——QT事件机制分析

QT开发(六十三)--QT事件机制分析 一.事件机制 事件是由系统或者QT平台本身在不同的时刻发出的.当用户按下鼠标.敲下键盘,或者是窗口需要重新绘制的时候,都会发出一个相应的事件.一些事件在对用户操作做出响应时发出,如键盘事件等:另一些事件则是由系统自动发出,如计时器事件. 事件的出现,使得程序代码不会按照原始的线性顺序执行.线性顺序的程序设计风格不适合处理复杂的用户交互,如用户交互过程中,用户点击"打开文件"将开始执行打开文件的操作,用户点击"保存文件"将开始执

QT开发(五)——窗口组件和窗口类型

QT开发(五)--窗口组件和窗口类型 一.窗口组件 图形用户界面由不同的窗口和窗口组件构成,<QtGui>头文件包含窗口组件,对应QT中的GUI模块,QT以组件对象的方式构建GUI. 组件的类型: A.容器类(父组件)用来包含其他的界面组件 B.功能类(子组件)用于实现特定的交互功能 QT中没有父组件的顶级组件叫窗口. QWidget是容器组件,继承自QObject类和QPaintDevice类,QObject类是所有支持QT对象模型的基类,QPaintDevice类是QT中所有可绘制组件的基

QT开发(六十五)——QT样式表编程实例

QT开发(六十五)--QT样式表编程实例 一.QComboBox组合框样式定制 1.基本定义 QComboBox  {     border: 1px solid gray;     border-radius: 3px;     padding: 1px 2px 1px 2px;  # 针对于组合框中的文本内容     min-width: 9em;   # 组合框的最小宽度 } QComboBox::drop-down {     subcontrol-origin: padding;