Quick--组件与基本元素

1 简介

2 根组件定义

id
自定义属性property
信号signal
JavaScript function
自带属性设置object properties
子控件child objects
状态states
动画animation、渐变transitions

2.1 id

2.1.1 介绍

在声明组件时,可以同时声明其“id”属性。“id”属性是该组件的代号,声明该属性的好处是,可以被它的作用域为:。同一qml文件中,每个控件都可以设置id属性,且不能相同

2.1.2 命名规则

  • 由字母组成,首字母必须小写,以小驼峰的形式命名。
  • 以控件类型结尾,例如:将Button的id设置为:xxxxBtn 或 xxxxButton,
    将Text的id设置为: xxxxTxt 或 xxxxText,将ComboBox的id设置为: xxxxCmb 或 xxxxComboBox,这样根据id就可以知道其对应的是什么控件。
  • 只有在明确知道其控件的缩写时,才能在id中使用缩小,否则一律使用控件全称。
  • 控件默认不设置id属性,若某个控件的id需要被使用(控件间存在关联关系),才要设置id。例如控件的布局存在相对位置的关系或控件间的属性在逻辑上存在依赖关系等,则需要设置id,例如:
Item{
      width: 200
      height: 300
      Button{
          id: saveBtn
          width: 60
          height: 30
          text: "Save"
      }
      Button{
          anchors {
              top: saveBtn.bottom
              topMargin: 10
              left: saveBtn.left
          }
          width: 60
          height: 30
          visible: saveBtn.visible
      }
  }
  • 当子控件要使用父控件的属性或根据父控件设置相对位置时,不要使用父控件的id,用parent代替id。
Item {
    id: root
    width: 800
    height: 480
    Rectangle{
        id: testRect
        anchors.centerIn: parent
        width: parent.width/2
        height: 200
        color: "red"

        Button{
            id: testBtn
            width: parent.width/2
            height: 40
            text: "1233"
            highlighted: (parent.color === "red") ? false : true
        }

    }
}
  • 一个qml文件中,设置id的个数不要超过7个,多余7个,则要进行qml代码的拆分,建议设置3到4个。
  • 同一个qml文件中的控件id在文件中是通用的,但是delegate中的控件id除外,delegate中控件id只在delegate中有效,外部访问无效。因为 delegate为Component类型,外界无法访问。通俗点讲,就是delegate一般用来承载model数据的显示,一个id对于多个数据显示控件,外部在使用id时,无法定位当前使用是哪个数据控件的id。
ListView {
        id:listView
        anchors.centerIn: parent
        width: 160
        height: 240

        model: Qt.fontFamilies()

        delegate: ItemDelegate {
            id:fontDelegate
            text: modelData
            width: parent.width
            highlighted: ListView.isCurrentItem
            onClicked:{
                listView.currentIndex = index
                console.log("clicked:", modelData)
            }
        }
    }
    ItemDelegate的id名称fontDelegate,是不能在ItemDelegate之外被使用的。

2.2 property属性

2.2.1 介绍

在qml代码中,为了方便外界使用本自定义控件或者便于qml文件内部控件之间的关联,常需要自定义一些属性。
一个property是对象的一个属性,可以被赋为静态值或者是绑定到动态表达式上。一个property的值可以被其它的对象读取。一般情况下,property属性也可以被其它对象修改,除非该QML类型明确指定该property属性不能被修改。

2.2.2 命名规则

属性名称必须是以小写字母开头,仅由字母、数字和下划线组成,由 名词或形容词+名词 的小驼峰形式组合而成。
当定义的属性仅限qml内部使用时,才会用到_,这样的私有属性的命名必须以两个下划线(__)开始

property var __locale: Qt.locale()

2.2.3 自定义属性

property <propertyType> <propertyName> : value

定义一个自定义的property属性也就为该property属性隐式的创建了一个value-change信号,也就是关联了一个名为 onChanged的signal handler。就是property属性的名称,而且首字母要大写。

 Rectangle {
        property string someText: “ ”
        onSomeTextChanged: console.log("The someText will be: " + someText)
    }
 * 自定义的属性必需要有初始值,除了Object Types
 * 常见自定义的属性类型:
 * bool,double,int,real,string,url,var,list
 * bool:true/false。
 * double:双精度实数,有小数点。
 * int:整数,可以是负数、0、正数。
 * real:实数,有小数点。
 * string:字符串。
 * url:资源路径,可以是绝对路径或相对路径,相对路径时就会被转换为 * URL对象,如果使用了Qt资源系统,就要用“qrc:///”代替“:/”。
 * var:基本类型是通用的类型,可以保存任意类型的值,包括lists和objects:
 * 任何标准的JavaScript类型都可以使用通用的var类型创建和存储。
 * 如果声明一个属性用于存储列表值,但不一定是存储QML对象类型值,这个时候你就需要声明var的property属性。
property var someNumber: 1.5
    property var someString: "aaa"
    property var someBool: true
    property var someList: [2,5,"one","two"]
    property var someObject: Rectangle {
                                width: 100
                                height: 100
                                color: "red"
                            }
   property var theArray: new Array()
   property var theDate: new Date()

任何的QML对象类型都可以被用作property属性类型
自定义QML类型也是

property Item someItem
property Rectangle someRectangle

2.2.4 属性别名

属性别名就是保存对另一个属性的引用。
属性别名需要使用alias关键字代替属性定义中的property类型,右边的值必须是合法的引用别名:

 property alias <name> : aliasreference
Rectangle {
    id: rootRect
    // 引用属性
    property alias color: blueRect.color
   // 引用对象
    property alias theRect: blueRect

    color: "red"

    Rectangle {
        id: blueRect
        color: "#1234ff"
    }
}

如果为一个已经存在属性创建一个同名的属性别名,这就会覆盖已经存在的属性。上面的代码中定义的color属性,会替代Rectangle原有的color属性,为了避免已有属性被覆盖的问题,定义的属性别名不能与已有属性相同。
若所引用的属性不是已经存在属性,则定义的属性别名要与引用的属性名称相同。

Rectangle {
    id: rootRect
    property alias count: nameList.count
    property alias currentIndex: nameList.currentIndex
    color: "red"
    ListView{
        id: nameList
    }
}
Rectangle没有count和currentIndex属性,则要将属性别名与引用属性名设置成一样。

只有在组件完全初始化之后属性别名才会被激活。如果未初始化的别名被引用了就会产生错误。为一个属性别名产生属性别名也会导致错误

property alias sureBtn: testBtn
property alias text: sureBtn.text
Button{
    id: testBtn
    width: 100
    height: 40
    text: "1233"
}
Component.onCompleted: console.log("text="+text)
产生的错误提示: Invalid alias reference. Unable to find id "sureBtn"

2.2.5 只读属性

readonly property <propertyType> <propertyName> : <initialValue>

只读属性必须在初始化的时候指定值。一旦只读属性被初始化了,它就不可能再被赋值了,无论是赋值(使用”=”)还是其它的方式。

2.3 信号

2.3.1 介绍

当一个信号发射了,对象可以通过signal handler被通知。

signal <signalName>[([<type> <parameter name>[, ...]])]
Item{
    id: root
    width: 100
    height: 40
    MouseArea{
        anchors.fill: parent
        onClicked: console.log("Click!")
    }
}

2.3.2 命名规则

  • 信号的命名规则遵循属性的命名规则,以小驼峰的形式命名。
  • 如果信号不带参数,则一律不使用()
  • 如果信号带参数,参数要写参数类型。

信号参数的命名规则:

  • msg+大驼峰形式
  • 必须以“msg”开头,便于标识是信号参数。
signal clicked
signal hovered(string msgInfo)
signal activated(real msgXPosition, real msgYPosition)

2.4 js代码

自定义的js函数,可以带参数,也可以不带出参数,且参数不用指明参数类型,因为函数的参数类型默认是万能的var类型。
函数名由字母和_组成,且首字母必须是小写,即以小驼峰的形式命名

function addZero(num){
    if(num < 10)
        return "0"+num
    else
        return num
}

函数返回时不要使用圆括号。
当定义的js函数,仅能在本qml文件使用,即使私有函数时,此函数的命名才用到_, 且是以双下划线(__)开始 + 小驼峰的方式命名

function __factorial(a) {
    a = parseInt(a);
    if (a <= 0)
        return 1;
    else
        return a * factorial(a - 1);
}

2.4 js文件

当一个qml文件中的js代码较多即:js函数代码超过80行时,应根据其分类或应用逻辑单独作成一个js文件,再将js文件导入qml文件。

2.4.1 js文件导入

qml中导入的js文件必须要有别名,别名的命名规则:
以大驼峰的形式命名
由js文件名中除了_和impl以外的字母组成

 import "jsfile_impl.js" as Jsflie

在js文件中导入另一个js文件的2种方法

.import "filename_imp.js" as Filename
Qt.include "filename.js"`

2.5 布尔表达式

在布尔表达式中,逻辑运算符 && 和|| 两边的条件表达式根据逻辑需要添加圆括号()

2.6 状态机

  • 在qml中,状态是定义在state类型中的一系列属性配置,不同的配置可能有不同的作用,为了方便起见,State元素都有一个when属性,可以绑定表达式来改变状态,当绑定的表达式评估为true,状态改变;当表达式评估为false,状态会退回到default state。
  • 显示一些UI控件,隐藏另一些。
StateGroup {
    states: [
        State {
            name: "xxx"
            when: visible
            PropertyChanges {
                target: xxxBtn
                visible: true
            }
            PropertyChanges {
                target: yyyBtn
                visible: true
            }
            PropertyChanges {
                target: zzzBtn
                visible: fasle
            }
        }
    ]
}

启动、暂停、停止动画。

StateGroup {
    states: [
        State {
            name: "start"
            when: 0 == animationState
            PropertyChanges {
                target: imageAnimation
                running: true
            }
        },
        State {
            name: "pause"
            when: 1 == animationState
            PropertyChanges {
                target: imageAnimation
                paused: true
            }
        },
        State {
            name: "stop"
            when: 2 == animationState
            PropertyChanges {
                target: imageAnimation
                running: false
            }
        }
    ]
}

改变某个特定Item的property的值。

StateGroup {
    states: [
        State {
            name: "color"
            when: bChanged
            PropertyChanges {
                target: rootRect
                color: "red"
            }
        },
        State {
            name: "enabled"
            when: disabled
            PropertyChanges {
                target: rootRect
                enabled: false
            }
        }
    ]
}

显示一个不同的view或screen。

 StateGroup {
   states: [
       State {
           name: "xxx"
           when: 0 == loaderState
           PropertyChanges {
               target: xxxLoader
               source: "Xxx.qml"
           }
       },
       State {
           name: "yyy"
           when: 1 == loaderState
           PropertyChanges {
               target: xxxLoader
               source: "Yyy.qml"
           }
       },
       State {
           name: "zzz"
           when: 2 == loaderState
           PropertyChanges {
               target: xxxLoader
               source: "Zzz.qml"
           }
       }
   ]
}

在某种新的状态下执行某些脚本。

// statetest.js
function getColor()
{
    return "green";
}

// test.qml
import "statetest.js" as StateTest
Rectangle{
    id: rect
    width: 50; height: 50
    color: "red"
    MouseArea {
        anchors.fill: parent
        onClicked: rect.state = "changedColor"
    }
StateGroup {
    states:
        State {
            name: "changedColor"
            StateChangeScript{
                name: "myScript"
                script: rect.color = StateTest.getColor()
            }
        }
    }
}

向用户呈现不同的操作和功能

Rectangle {
    id: rect
    width: 120; height: 120
    color: "black"
    Rectangle { id: myRect; width: 50; height: 50; color: "red" }
    StateGroup {
        states:
            State {
                name: "reanchored"
                AnchorChanges { // 改变 myRect 的anchors属性
                target: myRect
                anchors.top: rect.top
                anchors.bottom: rect.bottom
            }
            PropertyChanges {
                target: myRect
                anchors.topMargin: 10
                anchors.bottomMargin: 10
            }
        }
    }
    // 鼠标事件
    MouseArea {
        anchors.fill: parent
        onClicked: rect.state = "reanchored"
    }
}

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

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"
        }
    }
}
  • states中每个state之间的触发条件与PropertyChanges中的属性之间不要有关联,若有关联,可能会形成死循环。
  • 在qml中使用states时,一定要加上父层StateGroup,这样可以避免与原始控件中state名相同的state相冲突,产生无法预料的问题。
  • 能用条件运算符替代states的地方,尽量用条件运算符,不要用states。条件运算符的执行速度比state快。
StateGroup {
    states:
        State {
            name: "name"
            when: bChanged
            PropertyChanges {
                target: root
                color: "red"
            }
        }
}
应该修改为
color: bChanged ? "red" : "white"`

同一个State中有多个PropertyChanges,PropertyChanges的target不能设置一样,否则只执行第一个PropertyChanges。

StateGroup {
    states:
        State {
            name: "name"
            when: bChanged
            PropertyChanges {
                target: root
                color: "red"
            }
            PropertyChanges {
                target: root
                border.color: "red"
            }
        }
}
应该修改为
StateGroup {
    states:
        State {
            name: "name"
            when: bChanged
            PropertyChanges {
                target: root
                color: "red"
                border.color: "red"
            }
        }
}

3 内部组件

与“根组件定义”相同,但是其属性、信号、方法命名需添加双下划线("__")前缀。

Item {
        id: root
        width: 800
        height: 480
        Item {
            id: subItem

            property bool __updateState:false

            signal __clicked

            function __doSomething(x)
            {
                return x+subItem.x
            }

            width: 400
            height: 400

        }
    }

4 视觉元素

元素可以分为视觉元素和非视觉元素。视觉元素(如Rectangle)具有几何形状,通常在屏幕上显示一个区域。非视觉元素(如Timer)提供一般用于操作视觉元素的常规功能。
基本视觉元素,例如Item,Rectangle,Text,Image和MouseArea。但是,通过使用Qt Quick Controls 2模块,可以创建由标准平台组件(例如按钮,标签和滑块)构建的用户界面。

4.1 item元素

Item是所有视觉元素的基础元素,因为所有其他视觉元素都继承自Item。它本身不会绘制任何内容,而是定义所有可视元素共有的所有属性:
在这里插入图片描述

4.2 Rectangle元素

该Rectangle扩展Item并增加了填充颜色吧。此外,它支持由border.color和定义的边框border.width。要创建圆角矩形,可以使用radius属性。

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

在这里插入图片描述

  • 有效的颜色值是SVG颜色名称中的颜色(请参阅 http://www.w3.org/TR/css3-color/#svg-color)。您可以以不同的方式在QML中提供颜色,但是最常见的方式是RGB字符串(’#FF4444’)或作为颜色名称(例如’white’)。
  • 矩形还支持自定义渐变
Rectangle {
        id: rect1
        x: 12; y: 12
        width: 176; height: 96
        gradient: Gradient {
            GradientStop { position: 0.0; color: "lightsteelblue" }
            GradientStop { position: 1.0; color: "slategray" }
        }
        border.color: "slategray"
    }
梯度由一系列梯度停止点定义。每个停靠点都有位置和颜色。该位置标记了y轴上的位置(0 =顶部,1 =底部)。对的颜色GradientStop标记的颜色在该位置。    

无法创建成角度的渐变。为此,最好使用预定义的图像。一种可能性是仅用渐变旋转矩形,但要注意,旋转的矩形的几何形状不会改变,因此会引起混乱,因为元素的几何形状与可见区域不同。从作者的角度来看,在这种情况下最好使用设计的渐变图像。
在这里插入图片描述

4.3 Text元素

具体使用见QML学习(四)——<Text显示>
要显示文本,可以使用Text元素。它最显着的属性是texttype 的属性string。元素根据给定的文本和所使用的字体计算其初始宽度和高度。字体可以使用字体属性组的影响(例如font.family,font.pixelSize…)。要更改文本的颜色,只需使用color属性。

Text {
        text: "The quick brown fox"
        color: "#303030"
        font.family: "Ubuntu"
        font.pixelSize: 28
    }

在这里插入图片描述
可以使用horizontalAlignment和verticalAlignment属性将文本对齐到每一边和中心。要进一步增强文本渲染效果,可以使用style和styleColor属性,该属性允许您以轮廓,凸起和凹陷模式渲染文本。对于较长的文本,您通常希望定义一个断点位置,例如A very…long text,这可以使用elide属性来实现。该elide属性允许您将滑动位置设置为文本的左侧,右侧或中间。如果您不希望出现“省略”模式的“ …”但仍然希望看到全文,则还可以使用wrapMode属性将文本换行(仅在显式设置宽度时才有效):

Text {
    width: 40; height: 120
    text: 'A very long text'
    // '...' shall appear in the middle
    elide: Text.ElideMiddle
    // red sunken text styling
    style: Text.Sunken
    styleColor: '#FF4444'
    // align text to the top
    verticalAlignment: Text.AlignTop
    // only sensible when no elide mode
    // wrapMode: Text.WordWrap
}

一个Text元素只显示给定的文本。它不呈现任何背景装饰。除了渲染的文本,该Text元素也是透明的。为文本元素提供合理的背景是整体设计的一部分。
请注意,Text初始宽度(高度)取决于文本字符串和字体集。甲Text没有设定宽度和没有文本元素将不可见,作为初始宽度将为0。
通常,当您要布局Text元素时,需要区分在Text元素边界框内对齐文本还是在元素边界框本身之间对齐。在前一种情况下,您想使用horizontalAlignment和verticalAlignment属性,在后一种情况下,您想操纵元素的几何形状或使用锚点。

4.4 Image元素

一个Image元素能够显示各种格式的图像(例如PNG,JPG,GIF,BMP,WEBP)。有关支持的图像格式的完整列表,请查阅Qt文档。除了source提供图像URL 的明显属性外,它还包含一个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”)的本地路径,也可以是Web链接(例如“ http://example.org/home.png ”)。
Image元素使用PreserveAspectCrop还应该启用裁剪,以避免在Image边界外渲染图像数据。默认情况下,裁剪是禁用的(clip:false)。您需要启用剪贴(clip:true)来将绘画限制为边界矩形的元素。可以在任何视觉元素上使用。

4.5 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: 112; y: 12
        width: 76; height: 96
        border.color: "lightsteelblue"
        border.width: 4
        radius: 8
    }

5 非视觉元素

参考

1、qml编码规范与指导
2、A Book about Qt5
3、QML学习(四)——<Text显示>
4、QML图像、状态和动画–缩放、旋转和平移

展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 技术黑板 设计师: CSDN官方博客
应支付0元
点击重新获取
扫码支付

支付成功即可阅读