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机制方便。

相关推荐
kyriewen10 分钟前
别再每次都 Google 了:我整理了前端日常最常踩的 10 个 Git 坑,附速查表
前端·javascript·git
SmartBoyW1 小时前
深入ECMAScript规范:彻底搞懂JS隐式类型转换与底层ToPrimitive机制
前端·javascript
用户852495071842 小时前
解密 JavaScript 中的 this:谁才是真正的调用者?
javascript·面试
Heo2 小时前
Vite进阶用法详解
前端·javascript·面试
铁皮饭盒3 小时前
Next.js 风格路由内置?Bun FileSystemRouter 凭啥这么香
javascript
小林ixn4 小时前
别再背八股了!从 5 个真实场景彻底搞懂 JavaScript 的 this
javascript
东风破_4 小时前
JavaScript 面试常考的字符串算法:从反转字符串到回文判断
前端·javascript
巴勒个啦4 小时前
D3.js 入门实战:用力导向图可视化项目依赖关系
javascript
不好听6135 小时前
JavaScript 的 this 到底指向谁?
javascript·面试
触底反弹5 小时前
🔥 2026 年爆火的 Harness Engineering 到底是什么?从原理到实战一文讲透
javascript·人工智能·程序员