QML学习笔记(十七)QML的属性变更信号

前言

如果你已经比较熟悉QWidget,那你应该对信号的概念不会陌生。一般来说我想要用自定义的信号,都是需要进行单独定义的,即在该类的头文件中进行定义,该类还必须设置了Q_OBJECT这个宏定义,不然无法使用信号槽机制。

而在QML中的信号机制与之有些不同。比较特殊的一个就是属性变更信号,对于QML组件来说,你定义的任何属性,它都会给你设置一个信号,这个信号名称将采用on<属性名>Changed的格式。

这一点,其实在之前的学习中也简单应用过。让我们深入体验以下。

一、了解属性变更信号

width是一个十分常见的属性,而onWidthChanged就是与之对应的变更信号。

注意,这些信号是为了属性而生成的,不是为了信号而生成的。

我们熟悉的onClicked是一个处理器,它对应的信号是clicked,而clicked是鼠标单击时触发的信号,它不是一个属性。至于为什么会存在这个信号,不在本节的讨论范围内。

我们需要对这些概念有清晰的认知,切记不要混淆了。

我们新增一个工程QmlPropertyChangeHandler。

代码如下:

cpp 复制代码
import QtQuick 2.14
import QtQuick.Window 2.14

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Property changed handers")

    Rectangle {
        id: rectId
        width: 300
        height: width +50
        color: "dodgerblue"

        // 已有属性的变更信号处理器
        onWidthChanged: {
            console.log("Width change to: " + rectId.width)
        }

        onHeightChanged: {
            console.log("Height change to: " + rectId.height)
        }

        onColorChanged: {
            console.log("Color change to: " + rectId.color)
        }

        // 自定义属性
        property string descritption: "abcdefg"

        // 该属性的变更信号处理器
        onDescritptionChanged: {
            console.log("Descritption change to: " + rectId.descritption)
        }
    }

}

我们实现了一些已有属性的变更信号处理器,也设置了自定义属性descritption和其变更信号处理器。这里特别说一下,不只是int和string这种类型才可以触发变更信号,像color这种也可以。

最后,我们设置一下鼠标点击的代码,修改这些属性:

cpp 复制代码
        MouseArea{
            anchors.fill: parent
            // 鼠标点击时,修改矩形宽度和描述
            onClicked: {
                rectId.width += 20
                rectId.descritption = "New data"
                rectId.color = "Orange"
            }
        }

二、观察打印信息

运行代码,发现此时已经有一条打印了。

明明我都还没按下鼠标,为什会有这一条呢?

原因是矩形的height值是和width进行了属性绑定的,当初始化width的时候,也就意味着对height进行了修改,自然就会触发这里的变更信号处理器。这一点我们要有灵敏的察觉,不然以后可能会导致奇怪的为题。

然后我们点击按钮,观察现象:

可以看到,这些打印信息都被打印悉数出来了,并且是根据我们代码的顺序来触发的,矩形的颜色也得到了更改。

三、QML中信号机制的触发顺序

到这里,其实本节的学习就结束了。可我突然有个疑问,在QML中这样的一种信号槽,它的触发顺序到底是怎样的呢?于是我稍作修改了一下:

cpp 复制代码
        MouseArea{
            anchors.fill: parent
            // 鼠标点击时,修改矩形宽度和描述
            onClicked: {
                console.log("1")
                rectId.width += 20
                console.log("2")
                rectId.descritption = "New data"
                console.log("3")
                rectId.color = "Orange"
                console.log("4")
            }
        }

结果我发现打印信息变成了:

cpp 复制代码
qml: Height change to: 350
qml: 1
qml: Width change to: 320
qml: Height change to: 370
qml: 2
qml: Descritption change to: New data
qml: 3
qml: Color change to: #ffa500
qml: 4

这意味着,这里使用的属性变更处理器就是同步回调的------这一点也符合Qt中对于信号槽机制的定义:同一线程中的信号槽,默认是同步触发的

四、总结

这节的内容也比较简单好懂,但属性变更信号和其处理器这个机制,在传统QWidget中应该是没有的。如果你想要监听类中的某个变量的变化,那可就没这么方便了。可能要单独设置setX这种接口,内部发送一个信号;又或者设置定时器去检测,总之绝对不可能先本节介绍的这种QML机制方便。

相关推荐
eqwaak02 小时前
Flask实战指南:从基础到高阶的完整开发流程
开发语言·后端·python·学习·flask
GilgameshJSS2 小时前
STM32H743-ARM例程9-IWDG看门狗
c语言·arm开发·stm32·单片机·嵌入式硬件·学习
Hello_Embed3 小时前
STM32 智能垃圾桶项目笔记(一):超声波模块(HC-SR04)原理与驱动实现
c语言·笔记·stm32·单片机·嵌入式软件·嵌入式项目
真的想不出名儿3 小时前
vue项目引入字体
前端·javascript·vue.js
hsjkdhs3 小时前
C++之拷贝构造(浅拷贝与深拷贝)、this指针、内联函数
c++
默|笙3 小时前
【c++】红黑树的部分实现
开发语言·c++
轩情吖3 小时前
Qt常用控件之QSpinBox
开发语言·c++·qt·控件·桌面级开发·qspinbox·微调框
掘根3 小时前
【Qt】输入类控件2——SpinBox,DateEdit,TimeEdit,Dial,Slider
开发语言·qt
月盈缺3 小时前
学习嵌入式的第四十一天——ARM——时钟与定时器
arm开发·学习