当前位置:网站首页>Qt中的事件处理
Qt中的事件处理
2022-06-30 12:17:00 【AlbertOS】
引入
事件不是信号与槽;
这两个概念很容易混淆,究其本质信号与槽其实是Qt用来处理事件的一种处理机制,我们不能把它混为一谈。
其实还有很多不同的事件处理机制的,例如js使用的事件绑定机制,windows采用的消息机制,详情大家可以看我另外几篇博客windows消息机制学习
事件是什么?
事件就是一件事情,或者说是一个操作行为,用户移动鼠标、点击鼠标、敲击键盘等等所有的操作都称为事件(系统也可以发出事件,如计时器事件等)
事件的具体实现方式
事件的实现是通过订阅发布模式实现的,即在代码运行中预先定义事件,在后面某个操作中触发这个预先定义好的事件,执行事件处理程序(具体的源码大家可以看看windows的官方文档)
在Qt中我们处理事件采用的链式处理,和浏览器的DOM2事件模型一致,共有三个过程:
- 事件捕获阶段(自上而下)
捕获指的是事件从Windows对象一直向下传播到目标元素,依次检查经过的节点是否绑定了事件监听函数,如果有则执行,不然 - 处于目标阶段
又称事件处理阶段,这个阶段执行目标元素绑定的监听事件 - 事件冒泡阶段(自下而上)
冒泡指的是事件从目标元素冒泡到Windows对象,依次检查经过的节点是否绑定了事件监听函数
为啥事件都处理还要再冒泡呢?我们来看一个代码就明白了!
void MyLabel::mousePressEvent(QMouseEvent * event)
{
if(event->button() == Qt::LeftButton) {
// do something
} else {
QLabel::mousePressEvent(event);
}
}
我们在子类中重写了事件函数,在鼠标按下的事件中检测,如果按下的是左键,做我们的处理工作,如果不是左键,则调用父类的函数,这可以说事件向上传递给父类去响应,也就是我们在子类中忽略了这个事件导致事件必须冒泡
我们可以把Qt的事件传递看成责任链结构,如果在事件捕获阶段子类没有找到事件处理函数,就会继续向其他类传递
(其实,Qt的事件对象都有一个 accept()函数和 ignore()函数。正如它们的名字,前者用来告诉 Qt,事件处理函数“接收”了这个事件,不要再传递;后者则告诉 Qt,事件处理函数“忽略”了这个事件,需要继续传递,寻找另外的接受者。在事件处理函数中,可以使用 isAccepted()来查询这个事件是不是已经被接收了)
我们很少使用 accept()和 ignore()函数,而是想上面的示例一样,如果希望忽略事件,只要调用父类的响应函数即可。记得我们曾经说过,Qt 中的事件大部分是 protected 的,因此,重写的函数必定存在着其父类中的响应函数,这个方法是可行的。为什么要这么做呢?因为我们无法确认父类中的这个处理函数没有操作,如果我们在子类中直接忽略事件,Qt 不会再去寻找其他的接受者,那么父类的操作也就不能进行,这可能会有潜在的危险。
但是有一个情景下,我们也必须使用accept()和ignore()函数,就是在窗口关闭的时候,你想有个询问对话框就必须要主动使用accept()函数去主动接受这个消息(也可以把他想成一种Hook机制,它将发送给QObject的消息给主动拦截下来了,用来处理自己的工作)
void MainWindow::closeEvent(QCloseEvent * event)
{
if(continueToClose()) {
event->accept();
} else {
event->ignore();
}
}
bool MainWindow::continueToClose()
{
if(QMessageBox::question(this,
tr("退出"),
tr("你确定要关闭窗口吗?"),
QMessageBox::Yes | QMessageBox::No,
QMessageBox::No)
== QMessageBox::Yes) {
return true;
} else {
return false;
}
}
参考
我们还可以站在网页编程的角度来定义事件:
事件是什么?事件模型?
浏览器还可以直接处理DOM0事件,Qt因为存在Windows类和Qtapplication类的交互的问题,我还不知道能不能直接在Qt窗口的DOM内直接写事件处理函数
边栏推荐
- How to detect 3D line spectral confocal sensors in semiconductors
- Swagger2 automatically generates API documents
- Double dqn notes
- Pinda general permission system (day 7~day 8)
- Mysql判断计算结果,除以100
- dataworks 同步maxcomputer 到sqlserver ,汉字变乱码了,请问怎么解决
- Android development interview real question advanced version (with answer analysis)
- 【一天学awk】内置变量的使用
- SuperMap iDesktop 常见倾斜数据处理全流程解析
- NoSQL - redis configuration and optimization
猜你喜欢

Visual studio configures QT and implements project packaging through NSIS

New function of SuperMap iserver11i -- release and use of legend

21. Notes on WPF binding

Shell基础入门

Linux系统Redis的安装

Vision based robot grasping: from object localization, object pose estimation to parallel gripper grasping estimation

iServer发布ES服务查询设置最大返回数量

Reading the table data of Tencent documents in the applet

rpm2rpm 打包步骤

Use of polarplot function in MATLAB
随机推荐
Linux系统Redis的安装
【300+精选大厂面试题持续分享】大数据运维尖刀面试题专栏(二)
90. (cesium chapter) cesium high level listening events
JMeter之事务控制器
Substrate 源码追新导读: Pallet Alliance 并入主线,
Idea has a new artifact, a set of code to adapt to multiple terminals!
Tencent cloud Database Engineer competency certification was launched, and people from all walks of life talked about talent training problems
海思3559 sample解析:venc
Mysql中 begin..end使用遇到的坑
Shell基础入门
Swagger2 automatically generates API documents
两批次纯牛奶不合格?麦趣尔回应:正对产品大批量排查抽检
Qt读写Excel--QXlsx工作表显示/隐藏状态设置4
Three ways for flinksql to customize udaf
Sword finger offer 05 Replace spaces: replace each space in the string s with "%20"“
STM32 移植 RT-Thread 标准版的 FinSH 组件
[surprised] the download speed of Xunlei is not as fast as that of the virtual machine
QT MSVC installation and commissioning
JMeter性能测试之相关术语及性能测试通过标准
SuperMap iClient3D 11i for Cesium三维场景中图例使用说明