QML快速入门(QmlBook第4章复现)

创建QML项目

目的:学习创建QML项目
参考blog:https://blog.csdn.net/encesu/article/details/95309010.
(QT开发版本:QT5.5.1)

步骤1:文件->新建文件或项目->其它项目->QT Quick Ui
新建QML项目
生成*.qmlproject和*.qml两个文件,运行效果如下
运行效果

QML快速入门(QmlBook第4章复现)

QML语法

按文章QmlBook-In-Chinese.pdf学习整理
从QML元素的层次结构来理解是最简单的学习方式。子元素从父元素上继承了坐标系统,它的x,y坐标总是相对应于它的父元素坐标系统。
利用简单的QML文件例子解释语法

import QtQuick 2.0

Rectangle {
    //name this element
    id:root

    //properties:<name>:<value>
    width: 120; height: 280

    //color property
    color: "#D8D8D8"

    //declare a nested element (child of root)
    Image{
        id:rocket

        //reference the parent
        x:(parent.width-width)/2;y:(parent.height-height)/2
        source:'assets/rocket.png'

    }

    //Another child of root
    Text{
        //un-name element

        //reference element by id
        y:rocket.y+rocket.height+10

        //reference root element
        width: root.width

        horizontalAlignment: Text.AlignHCenter
        text:'rocket'
    }

    //Actions
    MouseArea{
        anchors.fill: parent
        onClicked: {
            Qt.quit();
        }
    }

}

归纳如下:
1.import声明导入了一个指定的模块版本。一般来说会导入QtQuick2.0来作为初 始元素的引用。
2.每一个QML文件都需要一个根元素,就像HTML一样,根元素id通常可以命名为root(id:root)。
3.一个元素使用它的类型声明,然后使用{}进行包含。
4.元素拥有属性,他们按照name:value的格式来赋值。
5.任何在QML文档中的元素都可以使用它们的id进行访问(id是一个任意的标识 符)
6.元素可以嵌套,这意味着一个父元素可以拥有多个子元素。子元素可以通过访问parent关键字来访问它们的父元素。

属性(Properties)

元素使用他们的元素类型名进行声明,使用它们的属性或者创建自定义属性来定义。一个属性对应一个值,例如 width:100,text: ‘Greeting’, color: ‘#FF0000’。一 个属性有一个类型定义并且需要一个初始值。

import QtQuick 2.0
Rectangle{
    width:120;height:240
    Text {
        //(1) identifier
        id:thisLabel

        //(2) set x- and y- Position
        x:24;y:16

        //(3) bind weight to 2*width
        height:0.5*width

        //(4) custom property
        property int times:24

        //(5) property alias
        property alias anotherTimes:thisLabel.times

        //(6) set text appended by value
        text:"Greetings"+times

        //(7) font is a grouped property
        font.family: "Ubuntu"
        font.pixelSize: 24

        //(8) KeyNavigation is an attached property
        KeyNavigation.tab: otherLabel

        //(9) signal handle for property changes
        onHeightChanged: console.log('height:',height)

        //focus is needed to receive key events
        focus:true

        //change color based on focus value
        color:focus?"red":"black"
    }

    Text{
        //(1) identifier
        id:otherLabel
        x:24;y:64
        font.family: "Ubuntu"
        font.pixelSize: 24
        text:'fight!!!'

        //(4) focus is needed to receive key events
        focus:true
        //change color based on focus value
        KeyNavigation.tab: thisLabel
        color: focus?"red":"black"
    }
}

归纳如下:
1.利用修饰符"property"可以添加自定义属性(格式:“property 类型 标识符:初始值”)
2.通过修饰符alias属性别名添加属性(格式:“property alias 标识符:某一属性”)。alias关 键字允许我们转发一个属性或者转发一个属性对象自身到另一个作用域。我们 将在后面定义组件导出内部属性或者引用根级元素id会使用到这个技术。一个 属性别名不需要类型,它使用引用的属性类型或者对象类型。
3.属性绑定:一个属性可以依赖一个或 多个其它属性
4.一些属性是按组分配的属性。当一个属性需要结构化并且相关的属性需要联系 在一起时,我们可以这样使用它。另一个组属性的编码方式是 font{family: “UBuntu”; pixelSize: 24 }。
5.一些属性是元素自身的附加属性。这样做是为了全局的相关元素在应用程序中 只出现一次
6.对于每个元素你都可以提供一个信号操作

脚本(Scripting)

QML与JavaScript关系

import QtQuick 2.0

Rectangle {
    width:240;height:120

    Text{
        id:label

        x:24;y:24

        //custom counter property for space presses
        property int spacePressed:0

        text:'space key pressed times:'+spacePressed

        //handle for text changed
        onTextChanged:console.log("text change to:"+text)

        //focus is needed to receive key events
        focus:true

        //handle with some js
        Keys.onSpacePressed:{
            increment()
        }
        function increment(){
            spacePressed+=1
        }

        //function escape
        Keys.onEscapePressed: {
            label.text='0'

        }

    }

}

归纳如下:
QML的:(属性绑定)与JavaScript的=(赋值)是不同的。绑定是一个协议,并 且存在于整个生命周期。然而JavaScript赋值(=)只会产生一次效果。当一个新 的绑定生效或者使用JavaScript赋值给属性时,绑定的生命周期就会结束。例如一 个按键的操作设置文本属性为一个空的字符串将会销毁我们的增值显示:

基本元素

元素可分为可视化元素非可视化元素。可视化元素(如矩形框Rectangle)有着几何形状并可以在屏幕上显示;非可视化元素(例如计时器Timer)提供了常用的功能,通常用于操作非可视化元素。
本节专注于几个基础的可视化元素

基础元素对象(Item Element)

Item(基础元素对象)是所有可视化元素的基础对象,所有其它的可视化元素都继承自Item。它自身不会有任何绘制操作,但是定义了所有可视化元素共有的属性:

Geometry(几何属性)
  1. x,y(坐标)定义了元素左上角的位置;
  2. 2.width 和height(宽度和高度)定义元素的显示范围;
  3. 3.z(堆叠次序)定义元素之间的重叠顺序
Layout handling(布局操作)

anchors(锚定),包括左(left),右(right),上 (top),下(bottom),水平与垂直居中(vertical center,horizontal center),与margins(间距)一起 定义了元素与其它元素之间的位置关系。(在之后“布局元素”一节详细介绍)在这里插入图片描述在这里插入图片描述

Key handling(按键属性操作)

附加属性key(按键)和keyNavigation(按键定位)属 性来控制按键操作,处理输入焦点(focus)可用操作。

Transformation(转换)

缩放(scale)旋转(rotate)转换,通用的x,y,z 属性列表转换(transform),旋转基点设置(transformOrign)

Visual(可视化)

1.opacity(不透明度)控制透明度
2.visible控制元素是否显示
3.clip(裁剪)用来限制元素边界的绘制
4.smooth(平滑)用来提高渲染质量

State definition(状态定义)

states(状态列表属性)提供了元素当前所支持的状态 列表,当前属性的改变也可以使用transitions(转变)属 性列表来定义状态转变动画

Item(基本元素对象)通常被用来作为其它元素的容器使用。

矩形框元素(Rectangle Element)

Rectangle(矩形框)是基本元素对象的一个扩展
1.增加了一个颜色来填充它(color)
2.支持边界的定义,使用border.color(边界颜色),border.width(边界宽度)来 自定义边界
3.radius(半径)属性来创建一个圆角矩形

import QtQuick 2.0

Item{
    width:200
    height:120


    Rectangle{
        id:rect1
        x:12;y:12
        width:76;height:96
        color:'lightsteelblue'
    }
    Rectangle{
        id:rect2
        x:rect1.x+rect1.width+10;y:12
        width:76;height:96
        border.width: 4
        border.color: 'lightsteelblue'
        radius: 8
    }
}

在这里插入图片描述
颜色的命名是来自SVG颜色的名称(查看http://www.w3.org/TR/css3-color/#svg-color.可以获取更多的颜色名称)。你也可以使用其它的方法来指定颜 色,比如RGB字符串(’#FF4444’),或者一个颜色名字(例如’white’)
此外,填充的颜色与矩形的边框也支持自定义的渐变色

    Rectangle{
        id:rect3;
        x:rect2.x+rect2.width+10;y:12
        width:76;height:96
        color: "#104b51"
        gradient: Gradient {
            GradientStop {
                position: 0.00;
                color: "#104b51";
            }
            GradientStop {
                position: 1.00;
                color: "#ffffff";
            }
        }

一个渐变色是由一系列的梯度值定义的。每一个值定义了一个位置与颜色。位置标 记了y轴上的位置(0 = 顶,1 = 底)。GradientStop(倾斜点)的颜色标记了颜色 的位置。
这个函数无法创建一个梯形,最好使用一个已有的图像来创建梯形。

文本元素(Text Element)

使用Text元素(Text Element)显示文本。可以使用字体属性组(font property group)来改变当前字体,例如font.family ,font.pixelSize等等

import QtQuick 2.0

Rectangle {
    width:240;
    height:240
    Text{
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.verticalCenter: parent.verticalCenter
        text:'Nice Weather'
        color:'lightsteelblue'
        font.family: 'Ubuntu'
        font.pixelSize: 28
    }
}

在这里插入图片描述
文本可以使用horizontalAlignment与verticalAlignment属性来设置它的对齐效果。为了提高文本的渲染效果,可以使用style和styleColor属性来配置文字的外框效果,浮雕效果或者凹陷效果。对于过长的文本,可能需要使用省略号来表示,例如Avery…longtext,可以使用elide属性来完成这个操作。elide属性允许你设置文本左边,右边或者中间的省略位置。如果不想’…'省略号出现,并且希望使用文字换行的方式显示所有的文本,可以使用wrapMode属性(这个属性只在明确设置了宽度后才生效):

import QtQuick 2.0

Rectangle {
    width:400
    height:200
    Text{
        width:80
        height:120
        text:'a very long text11111111'
        //elide:Text.ElideMiddle
        style:Text.Sunken
        styleColor: '#FF4444'
        font.family: 'Ubuntu'
        font.italic: true
        font.pixelSize: 24
        wrapMode: Text.WordWrap
    }
}

在这里插入图片描述
通常你想要对文本元素布局时,你需要区分文本在文本元素内部的边界对齐和由元素边界自动对齐。前一种情况你需要使用horizontalAlignment和verticalAlignment属性来完成,后一种情况你需要操作元素的几何形状或者使用anchors(锚定)来完成。

图像元素(Image Element)

一个图像元素(ImageElement)能够显示不同格式的图像(例如PNG,JPG,GIF,BMP)。source属性(sourceproperty)提供了图像文件的链接信息,fillMode(文件模式)属性能够控制元素对象的大小调整行为。

    Image {
        x: 12; y: 12
        // width: 72
        // height: 72
        source: "assets/triangle_red.png"
    }
    Image {
        x: 12+64+12; y: 12
        // width: 72
        height: 72/2
        source: "assets/triangle_red.png"
        fillMode: Image.PreserveAspectCrop
        clip: true
    }

注意
一个URL可以是使用’/'语法的本地路径("./images/home.png")或者一个网络链接(“http://example.org/home.png”)。
注意
图像元素(Image element)使用PreserveAspectCrop可以避免裁剪图像数据被渲染到图像边界外。默认情况下裁剪是被禁用的(clip:false)。需要打开裁剪(clip:true)来约束边界矩形的绘制。这对任何可视化元素都是有效的。
建议
使用QQmlImageProvider可以通过C++代码来创建自己的图像提供器,这允许动态创建图像并且使用线程加载。

鼠标区域元素(MouseAreaElement)

为了与不同的元素交互,通常需要使用MouseArea(鼠标区域)元素。这是一个矩形的非可视化元素对象,你可以通过它来捕捉鼠标事件。当用户与可视化端口交互时,mouseArea通常被用来与可视化元素对象一起执行命令。

    Rectangle{
        id:rect1
        x:12;y:12
        width:76;height:96
        color:'lightsteelblue'
        MouseArea{
            id:area
            width:parent.width
            height:parent.height
            onClicked: rect2.visible=!rect2.visible
        }
    }
    Rectangle{
        id:rect2
        x:rect1.x+rect1.width+10;y:12
        width:76;height:96
        border.width: 4
        border.color: 'lightsteelblue'
        radius: 8
    }

在这里插入图片描述

组件(Components)

组件是一个可以重复使用的元素,QML提供几种不同的方法来创建组件。但是目前我们只对其中一种方法进行讲解:一个文件就是一个基础组件。一个以文件为基础的组件在文件中创建了一个QML元素,并且将文件以元素类型来命名(例如Button.qml)。你可以像任何其它的QtQuick模块中使用元素一样来使用这个组件。在我们下面的例子中,你将会使用你的代码作为一个Button(按钮)来使用。
注意
文件名首字母需要大写

//MyButton.qml
import QtQuick 2.5

Rectangle {
    id:root
    //只有根目录下的元素才能被输出
    signal beclicked
    property alias text2:label.text

    width:116;height:26
    color:'lightsteelblue'
    border.color:'slategray'

    Text{
        id:label
        anchors.centerIn: parent //将子控件放置在父控件中心
        text:'Start'
    }
    MouseArea{
        anchors.fill: parent //将子控件大小和方位设置与父控件相同,即覆盖
        onClicked: {
            root.beclicked()
        }
    }

}

我们在根级导出了文本和点击信号。通常我们命名根元素为root让引用更加方便。我们使用了QML的alias(别名)的功能,它可以将内部嵌套的QML元素的属性导出到外面使用。有一点很重要,只有根级目录的属性才能够被其它文件的组件访问。

//reusable_component.qml
import QtQuick 2.5

Rectangle {
    width:140
    height:120
    MyButton{
        id:button
        x:12;y:12
        text2:'Click me'
        onBeclicked: {
            status.text='Button clicked'
        }
    }
    Text{
        id:status
        anchors.top: button.bottom
        anchors.topMargin: 10
        anchors.left: button.left
        horizontalAlignment: Text.AlignHCenter //字体对齐方式为中心对齐
        width:116;height:26
        text:'waiting...'
    }
}


简单的转换(Simple Trasnformations)

QML元素对象通常能够被平移,旋转,缩 放
简单的位移是通过改变x,y坐标来完成的。旋转是改变rotation(旋转)属性来完成的,这个值使用角度作为单位(0~360)。缩放是通过改变scale(比例)的属性来完成的,小于1意味着缩小,大于1意味着放大。旋转与缩放不会改变对象的几何形状,对象的x,y(坐标)与width/height(宽/高)也类似。只有绘制指令是被转换的对象。

以下第一个文件为包含鼠标区域的图像元素
第二个文件是对3个图像元素平移,旋转,缩 放示例
antializing:true 为抗锯齿属性,常用于缩放图片

//ClickableImage.qml
import QtQuick 2.0

Image {
    id:root
    signal beclicked
    MouseArea{
        anchors.fill: parent
        onClicked: root.beclicked()
    }

}
//transformation.qml
import QtQuick 2.0

Rectangle {
    id:root
    width:background.width
    height:background.height
    Image{
        id:background
        source:'asserts/background.png'
        MouseArea{
            anchors.fill: parent
            onClicked: {
                image1.x=20
                image2.rotation=0
                image3.rotation=0
                image3.scale=1.0
            }
        }
    }
    ClickableImage{
        id:image1
        x:20;y:100
        source: 'asserts/circle_blue.png'
        smooth: true
        onBeclicked: {
            x+=10
        }
    }

    ClickableImage{
        id:image2
        x:160;y:100
        source:'asserts/box_green@2x.png'

        antialiasing: true
        onBeclicked: {
            image2.rotation+=25
        }
    }

    ClickableImage{
        id:image3
        x:260;y:100
        source:'asserts/triangle_red.png'
        antialiasing:true
        onBeclicked: {
            image3.rotation+=25
            image3.scale+=0.05
        }
    }

}

定位元素

有一些QML元素被用于放置元素对象,它们被称作定位器,QtQuick模块提供了Row,Column,Grid,Flow用来作为定位器。
注意
首先介绍一些基本元素,红色(red),蓝色(blue),绿色(green),高亮(lighter)与黑暗(darker)方块,每一个组件都包含了一个48乘48的着色区域。下面是关于RedSquare(红色方块)的代码:

//RedSquare.qml
import QtQuick 2.0

Rectangle {
    width:48;height:48
    color:'#ea7025'
    border.color: Qt.lighter(color)
}

Column元素

Column(列)元素将它的子对象通过顶部对齐的列方式进行排列。spacing属性用来设置每个元素之间的间隔大小。

import QtQuick 2.0

Rectangle {
    width:100
    height:160
    Column{
        id:mycolumn
        anchors.fill:parent
        spacing: 5
        BlueSquare{}
        BrighterSquare{}
        RedSquare{width:100}
    }
}

在这里插入图片描述

Row元素

Row(行)元素将它的子对象从左到右,或者从右到左依次排列,排列方式取决于layoutDirection属性。spacing属性用来设置每个元素之间的间隔大小。

import QtQuick 2.0

Rectangle {
    width:300
    height:50
    Row{
        id:myRow
        anchors.fill:parent
        spacing: 5
        BlueSquare{}
        BrighterSquare{}
        RedSquare{width:100}
        layoutDirection: Qt.RightToLeft//默认为Qt.LeftToRight
    }
}

在这里插入图片描述

Grid元素

Grid(栅格)元素通过设置rows(行数)和columns(列数)将子对象排列在一个栅格中。可以只限制行数或者列数。如果没有设置它们中的任意一个,栅格元素会自动计算子项目总数来获得配置,例如,设置rows(行数)为3,添加了6个子项目到元素中,那么会自动计算columns(列数)为2。属性flow(流)与layoutDirection(布局方向)用来控制子元素的加入顺序。spacing属性用来控制所有元素之间的间隔。

import QtQuick 2.0

BrighterSquare {
    width:160
    height:160
    Grid{
        rows:2
        columns:2
        spacing: 10
        anchors.centerIn: parent
        BlueSquare{}
        DarkerSquare{}
        Item{width:48;height:48}
        GreenSquare{}
        //RedSquare{}
    }
}

在这里插入图片描述

Flow元素

最后一个定位器是Flow(流)。通过flow(流)属性和layoutDirection(布局方向)属性来控制流的方向。它能够从头到底的横向布局,也可以从左到右或者从右到左进行布局。作为加入流中的子对象,它们在需要时可以被包装成新的行或者列。为了让一个流可以工作,必须指定一个宽度或者高度,可以通过属性直接设定,或者通过anchor(锚定)布局设置。

import QtQuick 2.0

BrighterSquare {
    width:200
    height:200
    Flow{
        anchors.fill:parent
        anchors.margins: 20
        spacing: 20
        BlueSquare{}
        DarkerSquare{}
        RedSquare{}
    }
}

在这里插入图片描述
最大化后
在这里插入图片描述

Repeater元素(不属于定位器)

通常Repeater(重复元素)与定位器一起使用。它的工作方式就像for循环与迭代器的模式一样。

  1. property variant colorArray:["#00bde3", “#67c111”, “#ea7025”]定义了一个颜色数组
  2. model: 16 为重复元素的个数
  3. Math.floor(Math.random()*3)为JS中的数学函数
  4. Repeater中循环时有一个索引index,初始为0,每次循环+1
import QtQuick 2.5

DarkSquare {
    id: root
    width: 252
    height: 252
    property variant colorArray: ["#00bde3", "#67c111", "#ea7025"]


    Grid{
        anchors.fill: parent
        anchors.margins: 8
        spacing: 4
        Repeater {
            model: 16
            Rectangle {
                width: 56; height: 56
                property int colorIndex: Math.floor(Math.random()*3)
                color: root.colorArray[colorIndex]
                border.color: Qt.lighter(color)
                Text {
                    anchors.centerIn: parent
                    color: "#f0f0f0"
                    text: "Cell " + index
                }
            }
        }
    }
}

在这里插入图片描述

布局元素(Layout Items)

QML使用anchors(锚)对元素进行布局。anchoring(锚定)是基础元素对象的基本属性,可以被所有的可视化QML元素使用。一个anchors(锚)就像一个协议,并且比几何变化更加强大。Anchors(锚)是相对关系的表达式,你通常需要与其它元素搭配使用。
在这里插入图片描述
一个元素有6条锚定线(top顶,bottom底,left左,right右,horizontalCenter水平中,verticalCenter垂直中)。在文本元素(TextElement)中有一条文本的锚定基线(baseline)。
在这里插入图片描述
每一条锚定线都有一个偏移(offset)值,在top(顶),bottom(底),left(左),right(右)的锚定线中它们也被称作边距。
对于horizontalCenter(水平中)与verticalCenter(垂直中)与baseline(文本基线)中被称作偏移值。
1.元素填充父元素

        GreenSquare{
            RedSquare{
                anchors.fill: parent//填充
                anchors.margins: 8//设置边距,不设置默认值为0,完全覆盖
                text:'(1)'
            }
        }      

2.元素左对齐它的父元素

        GreenSquare{
            RedSquare{
                width:1/2*parent.width
                anchors.left: parent.left
                anchors.leftMargin: 8
                text:'(2)'
            }
        }

3.元素的左边与父元素的右边对齐

        GreenSquare{
            RedSquare{
                width:1/2*parent.width
                anchors.left: parent.right
                //anchors.leftMargin: 8
                text:'(3)'
            }
        }

4.元素1与父元素水平中心对齐,元素2与元素1水平中心对齐,元素2顶端与元素1底端对齐

        GreenSquare{
            RedSquare{
                id:redSquare1
                y:8
                width:48;height:24
                anchors.horizontalCenter: parent.horizontalCenter
            }
            RedSquare{
                width:24
                anchors.horizontalCenter: parent.horizontalCenter
                anchors.top: redSquare1.bottom
                anchors.topMargin: 8
                text:'(4)'
            }
        }

5.元素在它的父元素中居中

        GreenSquare{
            RedSquare{
                width:1/2*parent.width
                anchors.centerIn:  parent
                //anchors.leftMargin: 8
                text:'(5)'
            }
        }

6.元素水平方向居中对齐父元素并向后偏移12像素,垂直方向居中对齐。
GreenSquare{
RedSquare{
width:1/2*parent.width
anchors.horizontalCenter: parent.horizontalCenter
anchors.horizontalCenterOffset: 12
anchors.verticalCenter: parent.verticalCenter
text:’(6)’
}
}
在这里插入图片描述
注意:
当所有方格MouseArea中打开了拖拽功能时(drag.target: parent),方格(2)(3)(4)可以上下移动,因为它们只有左边被固定住了,拖拽一个元素意味着会改变它的x,y坐标。anchoring(锚定)比几何变化(例如x,y坐标变化)更强大是因为锚定线(anchoredlines)的限制,我们将在后面讨论动画时看到这些功能的强大。

输入元素(Input Element)

文本输入(Text Input)

文本输入允许用户输入一行文本。这个元素支持使用正则表达式验证器来限制输入和输入掩码的模式设置。

import QtQuick 2.0

Rectangle {
    id:root
    width:200;
    height:80

    TextInput{
        id:input1
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.top: parent.top;
        anchors.topMargin:  10
        width:150
        height:30
        focus:true
        text:'Input1'
        font.family: 'Times New Roman'
        font.pixelSize: 20
        KeyNavigation.tab: input2
    }
    TextInput{
        id:input2
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.top: input1.bottom
        anchors.topMargin:  10
        width:150
        height:30
        text:'Input2'
        font.family: 'Times New Roman'
        font.pixelSize: 20
        KeyNavigation.tab: input1
        onFocusChanged: console.log('focuschanged')
    }

}

在这里插入图片描述
用户可以通过点击TextInput来改变焦点。为了支持键盘改变焦点,我们可以使用 KeyNavigation(按键向导)这个附加属性。

用户需要一些可见的修饰来鉴别这是一个输入元素,例如一个简单的矩形框。当你放置一个TextInput(文本输入)在一个元素中时,你需要确保其它的元素能够访问它导出的大多数属性。我们提取这一段代码作为我们自己的组件,称作TLineEditV1用来重复使用

import QtQuick 2.0

Rectangle {
    width:96;height:30
    color:'lightsteelblue'
    border.color: Qt.lighter(color)
    property alias text:input.text
    property alias input:input

    TextInput{
        id:input
        anchors.fill:parent
        anchors.margins: 4
        focus:true
        font.family: 'Times New Roman'
        font.pixelSize: 20
    }
}

在这里插入图片描述
利用TLineEditV1重写按键导航

import QtQuick 2.0

Rectangle {
    id:root
    width:200;
    height:80

    TLineEditV1{
        id:input1
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.top: parent.top;
        anchors.topMargin:  10
        width:150
        height:30

        text:'Input1'
        KeyNavigation.tab: input2
    }
    TLineEditV1{
        id:input2
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.top: input1.bottom
        anchors.topMargin:  10
        width:150
        height:30
        text:'Input2'
        KeyNavigation.tab: input1
    }

}


尝试使用Tab按键来导航,会发现焦点无法切换到input2上。这个例子中使用focus:true的方法不正确,这个问题是因为焦点被转移到input2元素时,包含TlineEditV1的顶部元素接收了这个焦点并且没有将焦点转发给TextInput(文本输入)。为了防止这个问题,QML提供了FocusScope(焦点区域)。

焦点区域(FocusScope)

一个焦点区域(focusscope)定义了如果焦点区域接收到焦点,它的最后一个使用focus:true的子元素接收焦点,它将会把焦点传递给最后申请焦点的子元素。我们创建了第二个版本的TLineEdit组件,称作TLineEditV2,使用焦点区域(focusscope)作为根元素。

import QtQuick 2.0

FocusScope{

    width:96;height:30
    property alias text:input.text
    property alias input:input


    Rectangle{
        anchors.fill: parent
        color:'lightsteelblue'
        border.color: Qt.lighter(color)
    }

    TextInput{
        id:input
        anchors.fill:parent
        anchors.margins: 4
        focus:true
        font.family: 'Times New Roman'
        font.pixelSize: 20
    }
}

利用TLineEditV2重写按键导航

import QtQuick 2.0

Rectangle {
    id:root
    width:200;
    height:80

    TLineEditV2{
        id:input1
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.top: parent.top;
        anchors.topMargin:  10
        width:150
        height:30
        focus:true
        text:'Input1'
        KeyNavigation.tab: input2
    }
    TLineEditV2{
        id:input2
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.top: input1.bottom
        anchors.topMargin:  10
        width:150
        height:30
        text:'Input2'
        KeyNavigation.tab: input1
    }

}

可以正常切换

文本编辑(Text Edit)

文本编辑(TextEdit)元素与文本输入(TextInput)非常类似,它支持多行文本编辑。它不再支持文本输入的限制,但是提供了已绘制文本的大小查询(paintedHeight,paintedWidth)。我们也创建了一个我们自己的组件TTextEdit,可以编辑它的背景,使用focusscope(焦点区域)来更好的切换焦点。

import QtQuick 2.0

FocusScope{

    width:96;height:input.height+30
    property alias text:input.text
    property alias input:input


    Rectangle{
        anchors.fill: parent
        color:'lightsteelblue'
        border.color: Qt.lighter(color)
    }

    TextEdit{
        id:input
        anchors.fill:parent
        anchors.margins: 4
        focus:true
        font.family: 'Times New Roman'
        font.pixelSize: 20
    }
}

按键元素(Key Element)

附加属性key允许你基于某个按键的点击来执行代码。例如使用up,down按键来移动一个方块,left,right按键来旋转一个元素,plus,minus按键来缩放一个元素。

import QtQuick 2.0

Rectangle {
    width:400;height:200
    color: "#3c3c3c"
    border.color: Qt.darker(color)
    Rectangle{
        id:square
        color:'red'
        width:48;height:48
        x:8;y:8
    }
    focus:true
    Keys.onLeftPressed: square.x-=8
    Keys.onRightPressed: square.x+=8
    Keys.onUpPressed: square.y-=8
    Keys.onDownPressed:  square.y+=8
    Keys.onPressed: {
        switch(event.key){
        case Qt.Key_Plus:
            square.scale+=0.05;
            break;
        case Qt.Key_Minus:
            square.scale-=0.05;
            break;
        }
    }

}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值