QML自学之路(四)-以QML语言定义对象类型

8 篇文章 0 订阅
3 篇文章 0 订阅

QML对象类型是由QML文档定义的。QML文档是一个符合QML语法的字符串,每一个QML文档定义了一个QML对象类型(这是QT官方文档中的定义,但是我对这个定义存在一些疑问,对于含有内联组件的情况下,qml文档应该不是一个连续的字符串,其中包含内联组件定义的字符串应该属于内联组件文档)。通常QML文档是在.qml文件中定义的。但是.qml文件中不一定只包含一个QML文档。因为可能存在内联组件定义,因此一个.qml文件可能包含多个QML文档。

一、通过QML文件定义对象类型

通过QML文件定义对象类型的方式很简单,只要将.qml文件以<TypeName>.qml 格式进行命名,并在这个文件中输入QML文档就可以了。QML引擎会自动识别这个文件中定义的QML对象类型。如果另一个.qml文件与<TypeName>.qml 文件在同一个目录中,那么这个文件可以直接使用<TypeName>对象类型。一个QML文档还可以通过import语句引入一个目录,此时,QML文档可以使用这个被引入的目录中定义的所有QML对象类型。<TypeName>命名有一定要求:它必须由字母或下划线做成,且必须以一个大写字母开头。

以下是一个自定义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!")
    }
}

// myapplication.qml
import QtQuick 2.0

SquareButton {}

在以上例子中,SquareButton.qml包含了一个QML文档,这个文档定义了SquareButton对象类型。myapplication.qml与SquareButton.qml文件在同一个目录中,因此它可以直接使用SquareButton对象类型。

二、以内联组件方式定义QML对象类型

有时,在一个新的文件中定义QML类型不太方便,那么,可以采用内联组件的方式在同一个.qml文件中定义多个QML对象类型。它的语法如下:

component <component name> : 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文件定义了两个QML对象类型,一个是Images对象类型,另外一个是LabeledImage对象类型。在这个.qml文件中LabeledImage对象类型可以直接使用。在其他.qml文件中需要以Images.LabeledImage形式进行使用。

qt官方文档中这里说的有些模糊,除了以上方式外,还可以通过Component类型定义一个QML对象类型。 以下是一个使用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 }
}

在以上这个例子中,Component类型定义了一个名为redSquare的对象类型。将redSquare赋值给Loader类型子对象的sourceComponent属性,会创建一个RedSquare类型的对象。Component类型定义的对象类型在使用的时候无法增加属性,也无法在当前.qml文件以外的底方使用这个对象类型。但是,之前提到的那种内联组件方式定义的对象类型,可以在其他.qml文件中使用,也可以在使用时增加它的属性。

三、自定义对象类型的属性访问

一个QML对象类型的根对象包含的所有属性,对外是可见的。(类似于C++中的public成员)。可以被此类型的对象进行访问。

// SquareButton.qml
import QtQuick 2.0
Rectangle {
    id: root
    property bool pressed: mouseArea.pressed
    signal buttonClicked(real xPos, real yPos)
    function randomizeColor() {
        root.color = Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
    }
    property int side: 100
    width: side; height: side
    color: "red"
    MouseArea {
        id: mouseArea
        anchors.fill: parent
        onClicked: (mouse)=> root.buttonClicked(mouse.x, mouse.y)
    }
}

// application.qml
import QtQuick 2.0
SquareButton {
    id: squareButton
    onButtonClicked: (xPos, yPos)=> {
        console.log("Clicked", xPos, yPos)
        randomizeColor()
    }
    Text { text: squareButton.pressed ? "Down" : "Up" }
}

在以上这个例子里,SquareButton对象类型的根对象是Rectangle类型的,因此,Rectangle类型的所有属性以及根对象自定义属性(pressed属性,side属性,buttonClicked信号,randomizeColor方法,)对外是可见的。在application.qml文件中可以对pressed属性进行访问,发送randomizeColor信号。

需要注意的是,所有定义在 SquareButton.qml的id不能被SquareButton类型对象访问。因此,在以上例子中通过squareButton.mouseArea.pressed形式访问mouseArea属性是错误的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值