QML 信号与响应方法的总结
以下内容为本人的著作,如需要转载,请声明原文链接微信公众号「englyf」https://www.cnblogs.com/englyf/p/16748191.html
如果面试过程中,面试官想了解你对 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。
好了,暂时介绍到这里,下回见......
QML 信号与响应方法的总结的更多相关文章
- C#中Form的Paint事件响应方法与重载虚方法OnPaint()的区别
Form_Paint()方法是Paint事件的响应方法,OnPaint是可重载的虚方法,OnPaint方法是调用Paint事件的,用哪一个,效果是一样,就看那一个方便了内部是这样实现的: protec ...
- QRadioButton类中Toggled()信号的使用方法
QRadioButton类中Toggled()信号的使用方法 1.说明 QRadioButton中,Toggled()信号是在Radio Button状态(开.关)切换时发出的,而clicked()信 ...
- Objective-C 【动态类型检测&响应方法】
------------------------------------------- 动态类型检测 代码: #import <Foundation/Foundation.h> @inte ...
- 初学QML之QML和C++混合方法
混合使用QML和C++的方法 1加载一个QML组件,然后从 C++对其进行操作: 2直接将一个C++对象及其属性嵌入到QML组件: 3定义一个新的QML元素(通过基于QOject的C++类)并在QML ...
- Android学习之六种事件响应方法汇总
java源码如下: 1.MainActivity.java源码 package com.example.responsetest; import android.app.Activity; impor ...
- 六.OC基础--1. id和instancetype类型,2.动态类型检测,3.响应方法,构造方法,4.重写构造方法,5.自定义构造方法
1. id和instancetype类型, id和instancetype类型区别: 1. id和instancetype都可以用来作为方法的返回值 2. id可以用来定义类型,instancetyp ...
- iOS 左右滑动 手势 响应方法
1. @property (nonatomic, strong) UISwipeGestureRecognizer *leftSwipeGestureRecognizer; @property (no ...
- Button的四种Click响应方法
Button用得挺多的,在这整理了下它的事件处理方法,发现实现方法还不少,我比较喜欢第二种,你呢,最常用哪一种? 实现一: Button bt_Demo = (Button)findViewById( ...
- java事件响应方法汇总(容器类监听、监听器类、AbstractAction、反射)
Java图形用户界面中,处理事件时所必须的步骤是: 1.创建接受响应的组件(控件)2.实现相关事件监听接口3.注册事件源的动作监听器4.事件触发时的事件处理 相应的可以通过以下的集中方式来作出事件响应 ...
随机推荐
- Scala(二)IO流 读取文件和保存文件
package com.shujia.scala import java.io.{BufferedReader, FileReader, FileWriter} import scala.io.{Bu ...
- 字节输出流的续写和换行和字节输入流InputStream类&FileInputStream类介绍
数据追加续写 每次程序运行,创建输出流对象,都会清空目标文件中的数据.如何保目标文件中的数据,还能继续添加新数据呢? public FileOutputStream(File file,boolean ...
- Python3.7+Django2.0.4配合Mongodb打造高性能高扩展标签云存储方案
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_141 书接上回,之前有一篇文章提到了标签云系统的构建:Python3.7+jieba(结巴分词)配合Wordcloud2.js来构 ...
- Odoo14 收发邮件服务器设置
# 维护邮箱的七个地方 # 1.settings中Discuss栏将External Email Servers勾选(启用外部邮件服务),然后维护Alias Domain(域名) # 2.Techni ...
- Java集合容器的深度理解
Java容器里有很多写好的容器API,这使我们很方便的可以存储.操作我们的数据. 下面是我写的容器的特点,一些容器的不同之处,从底层源码解析一下容器实现原理 一.常用的容器目录 上图可以看出,java ...
- React报错之Cannot find namespace context
正文从这开始~ 总览 在React中,为了解决"Cannot find namespace context"错误,在你使用JSX的文件中使用.tsx扩展名,在你的tsconfig. ...
- package.json 与 package-lock.json 的关系
模块化开发在前端越来越流行,使用 node 和 npm 可以很方便的下载管理项目所需的依赖模块.package.json 用来描述项目及项目所依赖的模块信息. 那 package-lock.json ...
- Javascript之异步循环打印这道小题
这道题,我相信很多前端从业者都知道,它本质上来说并不复杂,但是却可以有很深远的扩展,最终核心的主题其实就是异步的遍历,其中对于题目的初级解法,还涉及到一些作用域的知识.那么我们以最容易理解的解法入手, ...
- 【设计模式】Java设计模式 - 责任链模式
[设计模式]Java设计模式 - 责任链模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 目录 [设计模式]Java设计模式 - 责 ...
- Linux 定时器介绍
以下内容为本人的著作,如需要转载,请声明原文链接微信公众号「englyf」https://www.cnblogs.com/englyf/p/16651865.html 曾经常去沙县小吃,就为了蹭上一碗 ...