QML类型系统

基本类型

QML默认支持一些基本类型,使用它们时不需要import语句。

下面是QML语言提供的基本类型:

类型

描述

bool

true/false,以二进制存储。

double

带有小数点的数字,并以双精度IEEE浮点格式存储。

enum

命名枚举值。

int

整数,例如0、10或-20。取值范围为-2147483648至2147483647。

list

QML对象的列表。

real

带小数点的数字,例如1.2或-29.8。以双精度IEEE浮点格式存储。

string

带引号的自由格式文本字符串,例如“ Hello world!”。

url

资源定位符。可以是相对路径,也可以是绝对路径。

var

通用属性类型,可以引用任何数据类型。

小贴士:enum不能单独使用,必须结合其类型一起使用。list只能存储QML对象,而不能包含任何基本类型的值。

另外,QML的QtQuick模块也提供了一些基本类型:

类型

描述

color

可以通过SVG颜色名称(如"red"或"blue")、十六进制字符串(如"#RRGGBB"或"#AARRGGBB")、Qt全局对象的方法(如Qt.rgba()或Qt.hsva())来进行引用。

date

日期值(如"2020-12-31 23:59")。

font

字体类型(如font.family)。

matrix4x4

一个4x4的矩阵类型,支持幂运算。可以使用Qt.matrix4x4()函数来组成此类型的值。

point

具有x和y属性的类型(如"0, 20")。

quaternion

具有scalar, x, y和z属性的类型(如"1, 10, 10, 1",Qt.quaternion(1, 10, 10, 1))。

rect

具有x, y, width和height属性的类型(如"50, 50, 100x100",Qt.rect(50, 50, 100, 100))。

size

具有width和height属性的类型(如"150x50",Qt.size(150, 50))。

vector2d

二维向量类型。具有x和y属性(如"1, 2",Qt.vector2d(1,2);)。

vector3d

三维向量类型。具有x、y和z属性(如"0, 1, 0",Qt.vector3d(0, 1, 0))。

vector4d

四维向量类型。具有x、y、z和w属性(如"1, 2, 3, 4",Qt.vector4d(1,2,3,4);)。

示例如下:

property int count: 10
    property double weight: 100.0
    property string placeHolderText: "Hello QML"
    property color backgroundColor: "#F7F7F7"
    property size defaultSize: Qt.size(150, 50)
    property rect defaultRect: Qt.rect(50, 50, 100, 100)
    property vector2d defaultVector2d: Qt.vector2d(1,2)

    property int count: 10
    property double weight: 100.0
    property string placeHolderText: "Hello QML"
    property color backgroundColor: "#F7F7F7"
    property size defaultSize: Qt.size(150, 50)
    property rect defaultRect: Qt.rect(50, 50, 100, 100)
    property vector2d defaultVector2d: Qt.vector2d(1,2)

对象类型

QML对象类型用于实例化QML对象。它通过指定类型名称后跟一组包含该对象属性的花括号来声明对象的类型。对象类型名称必须由字母、数字或下划线组成,并且以大写字母开头。使用它们时需要import语句。每个QML文件都隐式定义了一个QML对象类型,该类型可以在其他QML文件中重复使用。

内置对象类型

QML提供了很多内置对象类型,如QtQuick模块中的RectangleTextImageTextInput等。QtQuick.Controls模块中的ButtonLabelCheckBoxPage等。

使用QML文件实现自定义对象类型

可以通过创建QML文件实现自定义QML对象类型。该文件名称同样必须由字母、数字或下划线组成,并且以大写字母开头。如下面创建一个SquareButton.qml文件:

// SquareButton.qml
    import QtQuick 2.0

    Rectangle {
        property int side: 100
        width: side; height: side
        color: "red"

        MouseArea {
            anchors.fill: parent
            onClicked: console.log("Button clicked!")
        }
    }

    // SquareButton.qml
    import QtQuick 2.0

    Rectangle {
        property int side: 100
        width: side; height: side
        color: "red"

        MouseArea {
            anchors.fill: parent
            onClicked: console.log("Button clicked!")
        }
    }

这样就可以在与SquareButton.qml文件同级目录的其他QML文件中使用SquareButton类型。

// myapplication.qml
    import QtQuick 2.0

    SquareButton {}

    // myapplication.qml
    import QtQuick 2.0

    SquareButton {}

通过qmlscene命令执行myapplication.qml文件,可以看到运行效果如下:

qml function参数 qml定义函数_QML



点击界面后,终端会有响应日志输出。

内联组件

有时,为一个类型创建一个新文件会很不方便。在这种情况下,可以使用内联组件来完成。内联组件是在QML文件中声明一个新组件。语法如下:

component  : BaseType {// declare properties and bindings here
    }
    component  : BaseType {// declare properties and bindings here
    }

在声明内联组件的文件中,可以直接通过名称引用该类型。

// Images.qml
    import QtQuick 2.15

    Item {
        component LabeledImage: Column {
            property alias source: image.source
            property alias caption: text.text

            Image {
                id: image
                width: 50
                height: 50
            }
            Text {
                id: text
                font.bold: true
            }
        }

        Row {
            LabeledImage {
                id: before
                source: "before.png"
                caption: "Before"
            }
            LabeledImage {
                id: after
                source: "after.png"
                caption: "After"
            }
        }
        property LabeledImage selectedImage: before
    }

    // Images.qml
    import QtQuick 2.15

    Item {
        component LabeledImage: Column {
            property alias source: image.source
            property alias caption: text.text

            Image {
                id: image
                width: 50
                height: 50
            }
            Text {
                id: text
                font.bold: true
            }
        }

        Row {
            LabeledImage {
                id: before
                source: "before.png"
                caption: "Before"
            }
            LabeledImage {
                id: after
                source: "after.png"
                caption: "After"
            }
        }
        property LabeledImage selectedImage: before
    }

如果在其他文件中引用该内联组件,则必须在其前面加上组件名称。

// LabeledImageBox.qml
    import QtQuick 2.15

    Rectangle {
        property alias caption: image.caption
        property alias source: image.source
        border.width: 2
        border.color: "black"
        Images.LabeledImage {
            id: image
        }
    }

    // LabeledImageBox.qml
    import QtQuick 2.15

    Rectangle {
        property alias caption: image.caption
        property alias source: image.source
        border.width: 2
        border.color: "black"
        Images.LabeledImage {
            id: image
        }
    }

小贴士:内联组件不与声明它们的组件共享作用域,并且不可以嵌套使用。

JavaScript类型

QML可以支持JavaScript中的数据类型。如基本类型StringNumberBooleanNullUndefinedSymbol等。引用类型ObjectArrayFunctionDate等。

QML允许使用varlet语句在JavaScript表达式中声明一个变量,如下面的代码在QML中的JavaScript表达式里都是完全正常的:

var cars = new Array();
    cars[0] = "Cat";
    cars[1] = "Dog";
    cars[2] = "Panda";

    var cars = new Array();
    cars[0] = "Cat";
    cars[1] = "Dog";
    cars[2] = "Panda";
var sum = function (num1, num2) {
        return num1 + num2
    }
    console.log(sum(10, 20))

    var sum = function (num1, num2) {
        return num1 + num2
    }
    console.log(sum(10, 20))

小贴士:与QML不同,JavaScritp作为一种弱类型语言,它的变量是没有类型的,只有值才具有类型。变量可以随时持有任何类型的值。