首页 > 其他分享 >QML 信号与响应方法的总结

QML 信号与响应方法的总结

时间:2023-04-15 14:05:09浏览次数:42  
标签:总结 clicked 自定义 响应 QML 信号 connect

以下内容为本人的著作,如需要转载,请声明原文链接 微信公众号「englyf」https://mp.weixin.qq.com/s/8orMKb803oz_G0sSOnDjDw


如果面试过程中,面试官想了解你对 Qt 的理解有多少,少不了会涉及到信号槽这一块,毕竟这是 Qt 最经典的一项技术。

刚开笔,我可能有点狂妄了。

信号槽,分为两部分,信号和对信号响应的槽函数。在可视化开发过程中,无论你用 QWidget 还是 QtQuick 都可以运用到信号槽。QtQuick 是目前 Qt 公司主推的可视化框架了,当然不会缺失对信号槽的支持。

QtQuick 的模块提供了丰富的预定义信号,当然也允许用户自定义信号。

下面就斗胆总结一下在 QML 中信号槽的使用。

1. QtQuick 提供的预定义信号

这些信号都是Qt库里已经预定义好了的,为了使用这些信号,我们需要的是导入类型所在模块和定义响应过程即可。

上来就手掰一个栗子:比如,为了响应 MouseArea 的 clicked 信号,仅需要在 MouseArea 类型对象声明中添加以下形式的语句即可:

onClicked: {
    // do something ....
}

on后边紧跟着的信号名字 clicked 必须首字母大写。冒号后边如果仅是单语句,可以不用大括号{},多语句结尾可以添加分号;结尾。

提醒一下,这种对信号槽的使用方式,适用于信号所属对象的内部。因为这里边其实是包含了隐式的连接(信号和槽),在信号 signal 所属对象的内部直接声明槽函数。

槽函数声明,一般形式如下:

on<Signal>: {
    // do something ....
}

signal 首字母要大写。

2. 属性变化时会触发信号

假设声明了一自定义属性 property,当这个属性被修改后,QML 引擎会发射形式如下的信号

<property>Changed

可添加以下形式语句响应这个属性的变化:

on<Property>Changed: {
    // do something ....
}

在声明响应时,属性名 property 同样需要首字母大写。

无论是自定义的属性,还是预定义的属性,变化时引擎都会发射信号,这些信号响应的形式和上面信号的类似,只不过需要多加个 Changed

3. 附加类型对象Component的信号

简单点理解,QML 引擎会自动在 QML 文件里声明的对象中附加一个 Component 对象。当 QML 文件定义的顶层对象加载完成时,会触发 Component 对象的 completed 信号,为了响应此信号,可以添加以下形式语句:

Component.onCompleted: {
    // do something ....
}

关于 Component 更多信息可以参考

https://doc.qt.io/qt-6/qml-qtqml-component.html

4. 自定义信号

大多数时候,定义的 QML 对象都会需要在其中添加或多或少的自定义信号,同时也会需要定义相应的响应。

用以下形式声明自定义的信号

signal <name>[([<type> <parameter name>[, ...]])]

一般可视化的自定义的 QML 对象都会基于 Item 或者 Rectangle 来做扩展,包括添加自定义信号以及其它必要的功能等,其实这个过程也相当于对原有的类型做了派生(参考C++的习惯)。

Rectangle {
    id: root

    signal mysignal(int x, int y)

    MouseArea {
        anchors.fill: parent
        onPressed: root.mysignal(mouse.x, mouse.y)
    }
}

上面代码中,Rectangle 对象定义了信号 mysignal,带有整形参数x和y。然后添加了针对鼠标区域定义的组件 MouseArea,在其中通过信号槽去触发父对象的自定义信号 mysignal。

MouseArea 属于预定义类型,pressed 信号自带参数 mouse。更多信息可以参考下面的链接:

https://doc.qt.io/qt-6/qml-qtquick-mousearea.html#pressed-signal

自定义信号的处理形式和预定义信号一致,参考上面预定义信号的响应方法。

5. 通过信号的方法connect指定响应

关于 connect,简单的说,就是用于针对具体信号指定响应的方法或者触发的下一个信号。啰嗦点来讲,一个信号被触发了,那么它可以指定响应的方法,也可以指定触发下一个信号形成信号的连锁反应,这个过程就通过 connect 来指定。

如果你熟悉 Qt, 应该对 C++ 的 QObject::connect 方法不陌生。和 C++ 部分类似,QML 中也有 connect 方法,可以连接任意的(包括多个)信号和方法,但是 QML 的 connect 更灵活而且调用方式不太一样。不一样的是,C++ 中 QObject::connect 是静态方法,而 QML 的 connect 由信号提供。参考以下形式:

signal.connect(signal / function_name)

要注意一下,QML 对象的信号必须通过对象来引用。

看个例子:

Rectangle {
    id: root

    signal mySignal()
    // 信号响应处理
    onMySignal: console.log("clicked connect mySignal")

    // 普通方法
    function slt_clicked() {
      console.log("clicked connect slt_clicked");
    }

    Component.onCompleted: {
        mousearea.clicked.connect(slt_clicked);
        mousearea.clicked.connect(mySignal);
    }

    MouseArea {
        id: mousearea
        anchors.fill: parent
    }
}

通过上面的代码可知,在引用的组件 Component 的信号 completed 的响应中,通过另一个组件 mousearea 的信号 ( clicked ) 调用 connect 连接父组件的函数 slt_clicked 和信号 mySignal。

如果信号 clicked 带有参数,那么被连接的方法 ( slt_clicked ) 和信号 ( mySignal ) 也应该有同样数目的参数。

当 MouseArea 组件的信号 clicked 被触发后,可以看到下面的输出:

clicked connect slt_clicked
clicked connect mySignal

当然,如果连接不再需要,那么 disconnect 也是不能缺少的。disconnect 的作用和 connect 相反,专用于解绑已有连接,也是通过信号调用。

Rectangle {
    id: relay
    // ... 省略

    function removeSignal() {
        mousearea.clicked.disconnect(slt_clicked);
        mousearea.clicked.disconnect(mySignal);
    }
}

6. 处理任意对象的信号:

QtQuick 框架提供了一个超级好用的类型:Connections,它可以用于响应任意对象的信号(官方说法是generalized)。

大多数情况下,用于连接其它 QML 文件中定义的对象的信号,具体需要指定信号所属对象的 id。参考以下形式:

import QtQml

Connections {
    target: object_id

    onSignal: {
        // do something ....
    }
}

target 属性用于指定响应信号所属对象的 id。


好了,暂时介绍到这里,下回见......

标签:总结,clicked,自定义,响应,QML,信号,connect
From: https://blog.51cto.com/englyf/6192295

相关文章

  • 总结与归纳之数学
    (巨坑好吧)前言前置的知识正文同余问题大杂烩玄学:Miller-Rabin&Pollard-rho线性代数大杂烩组合数学大杂烩筛法反演问题大杂烩玄学:群论问题大杂烩多项式与生成函数大杂烩玄学:线性规划博弈论问题大杂烩微积分问题小杂烩?计算几何问题大杂烩......
  • JAVA 循环删除list中元素的方法总结
    摘要:介绍List集合实现元素边遍历边删除的方法,例如removeIf和迭代器iterator.remove()等。综述  List集合是我们开发中经常使用到的一种集合形式,有时候会遇到在遍历List集合时需要删除指定的元素。但在根据条件使用for循环或者增强的for循环遍历删除某些元素时却不能随心所欲地......
  • linux网络开发者定位问题常用工具和命令总结
    本文章来自我的微信个人技术公众号---网络技术修炼,公众号中总结普及网络基础知识,包括基础原理、网络方案、开发经验和问题定位案例等,欢迎关注。Linux网络开发者面临的问题往往比较复杂,因此需要使用一些工具和命令来进行定位和解决。在本篇博客中,我将总结一些常用的Linux网络开发......
  • vue3 父子组件共享响应式对象
    父组件<templatelang=""><div><divclass="greetings">按钮值:{{num}}</div><div><button@click="num++">按钮</button></div><div>iamparent</div&......
  • 总结20230414
    今天周五,一周课最多了,但是今天也是很开心的!今天上的是计算机网络、概率论、web应用开发技术、数学建模B。计算机网络讲的是ARP协议以及具体传输时的传输过程,这几节课感觉听得挺不错的,挺轻松的。概率论讲的是二维随机变量分布的函数以及习题,一开始听的有点懵,但是后来悟明白了,边......
  • ajax面试题总结
    转载请注明出处:1.ajax异步和同步的区别Ajax是一种基于JavaScript语言和XMLHttpRequest对象的异步数据传输技术,通过它可以使不用刷新整个页面的情况下,对页面进行部分更新。同步和异步是指客户端发送请求时,主线程是否会阻塞等待服务器的响应返回。同步请求在发送请......
  • pandas库简单用法总结
    简介pandas 是基于NumPy的一种工具,主要用途是做数据分析,对于初学者,比较常用的就是处理csv或者excel文件DataFrame数据结构DataFrame组成DataFrame是Pandas的重要数据结构之一,也是在使用Pandas进行数据分析过程中最常用的结构之一。DataFrame一个表格型的数据结构,既有......
  • 4.14每日总结
    今天做了什么:根据用户消费比例给出消费建议,识别微信截图信息并添加到记账页面,学习了cookie和session的使用遇到了哪些问题:拍照获得的bitmap的data有限制大小,导致识别图片模糊明天打算做什么:攻克拍照获得图片模糊......
  • 【考后总结】NOI 统一省选 2023
    文化课补完了,但是考试考炸了,所以来补题。D1T1火车站station实际上只需要判断从\(x\)能否一直向一个方向移动且每个位置能不能作为这个方向的终点站。区间覆盖差分一下即可。点击查看代码intn,m,x;intst[maxn][2],cov[maxn];boolvis[maxn];intmain(){freope......
  • 每日总结 4..14
    今天到该完成了售卖机的页面以及流程。进行了售卖记录的统计并存入数据库。为之后的每日收入汇总做好基础。   ......