您当前的位置: 首页 > 

龚建波

暂无认证

  • 4浏览

    0关注

    313博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

QML类型系统

龚建波 发布时间:2020-03-17 22:55:48 ,浏览量:4

目录

0.前言

1.基本类型

QML语言本身支持的基本类型

QML模块提供的基本类型

基本类型的属性改变行为

2.JavaScript类型

3.QML对象类型

通过QML文件定义对象类型

使用Component定义匿名类型

通过C++定义对象类型

0.前言

QML中可以使用的类型有多种来源,可能是:

  • QML语言本身支持的基本类型(如 int、var 等)
  • C++注册的QML模块(如使用 qmlRegisterType 注册类型)
  • QML写的模块 (如单独写一个 QML 文件来定义自己的组件)

但引擎都会对这些类型的属性和实例强制执行类型安全。

QML中的类型可以分为三种:

  • 基本类型(如 int、string)
  • JavaScript类型(如 Date、Array 等标准 JS 类型,可用 var 存储)
  • 对象类型(具有属性、信号、方法等)

(本节参照:https://doc.qt.io/qt-5/qtqml-typesystem-topic.html)

1.基本类型

引擎默认支持某些基本类型,不需要import语句,而有些则需要导入对应的模块。基本类型大多都可以在QML文件中作为属性类型,以下情况除外:

  • list 必须与 QML 对象类型结合使用

  • enumeration 不能直接使用,因为枚举必须由已注册的 QML 对象类型定义

QML语言本身支持的基本类型

(在QML中,所有实数都以双精度IEEE浮点格式存储,但是没搞懂为什么有了double还要加一个real)

QML模块提供的基本类型

QML模块可以使用更多基本类型扩展QML语言。如QtQuick模块提供的基本类型:

当前,只有Qt提供的QML模块可以提供其自己的基本类型,但是在将来的Qt QML版本中可能会有所改变。为了使用特定QML模块提供的类型,必须将该模块导入。

基本类型的属性改变行为

QML中组件的属性改变时会有对应的changed信号发出,但是对于一些有属性的类型,例如 font类型具有pixelSize,family和bold等属性,与对象类型的属性不同,基本类型的属性不提供它们自己的属性更改信号,只能为基本类型属性本身创建属性更改信号处理程序,即font即使只有字体改变,那发出的也是fontChanged信号,而不是fontFamilyChanged。只要基本类型任何属性发生更改,以及其本身发生更改时,就会发出基本类型的属性更改信号。

Text {
    // 这样写无效
    onFont.pixelSizeChanged: doSomething()

    // 这样也是无效
    font {
        onPixelSizeChanged: doSomething()
    }

    // 正确写法
    onFontChanged: doSomething()
}

(本节参照:https://doc.qt.io/qt-5/qtqml-typesystem-basictypes.html)

(所有基本类型:https://doc.qt.io/qt-5/qmlbasictypes.html)

2.JavaScript类型

QML引擎支持JavaScript对象和数组。可以使用通用var类型创建和存储任何标准JavaScript 类型。

import QtQuick 2.0

Item {
    property var theArray: []
    property var theDate: new Date()

    Component.onCompleted: {
        for (var i = 0; i < 10; i++)
            theArray.push("Item " + i)
        console.log("There are", theArray.length, "items in the array")
        console.log("The time is", theDate.toUTCString())
    }
}

(本节参照:https://doc.qt.io/qt-5/qtqml-typesystem-topic.html)

3.QML对象类型

QML对象类型是可以从中实例化QML对象的类型。QML对象类型是从QtObject派生的,并由QML模块提供。应用程序可以导入这些模块以使用它们提供的对象类型。QtQuick模块提供了常用的对象类型。此外,每个QML文件都隐式定义了一个QML对象类型,该类型可以在其他QML文件中重复使用。

QML对象类型的基本应用形式如下:

    Item{
        //后跟一组包含该对象属性的花括号
        
        //定义一个基本类型的name属性
        property string name: "gong jian bo"
        
        //定义一个方法
        function func(){}
    }
通过QML文件定义对象类型

此方式定义的类型,类型名一般为文件名,需要大写字母开头,可以包含字母数字下划线。如新建一个名为 “ MyButton.qml ” 的文件来自定义一个按钮组件。

 

该文件被引擎自动识别为QML类型的定义。此外,在解析QML类型名称时,以这种方式定义的类型会自动提供给引擎在直接目录中搜索的同一目录中的其他QML文件。 

使用Component定义匿名类型

从QML中创建对象类型的另一种方法是使用Component类型。这允许在QML文档中内联定义类型,而不是写一个单独的qml文件。

Item {
    id: root
    width: 500; height: 500

    Component {
        id: myComponent
        Rectangle { width: 100; height: 100; color: "red" }
    }

    Component.onCompleted: {
        myComponent.createObject(root)
        myComponent.createObject(root, {"x": 200})
    }
}

这里的myComponent对象本质上定义了一个匿名类型,可以使用Component::createObject实例化该匿名类型以创建此匿名类型的对象。

通过C++定义对象类型

首先,我们的C++类需要继承自QObject。

然后,使用qmlRegisterType函数注册普通的QML对象类型,使用qmlRegisterSingletonType函数注册单例类型等。

使用C++注册QML对象类型要注意的东西很多,如返回值/参数/属性的类型,一般只能把简单的类型暴露到QML中,如QVector,但是你要是写QVector,就不能识别了。我们可以通过QVariant对复杂类型装箱拆箱,虽然这样暴露到QML的数据类型可能无法在QML中直接操作,但如果在QML中两个C++注册的对象类型关连信号槽时参数是QML无法识别的情况下,应该能派上用场。

(本节参照:https://doc.qt.io/qt-5/qtqml-typesystem-objecttypes.html)

(本节参照2:https://doc.qt.io/qt-5/qtqml-cppintegration-definetypes.html)

(参照博客:https://blog.csdn.net/luoyayun361/article/details/86088763)

关注
打赏
1655829268
查看更多评论
立即登录/注册

微信扫码登录

0.2247s