accept()函数用来告诉Qt,事件处理函数“接收”了这个事件,不要再传递;ignore()函数则告诉Qt,事件处理函数“忽略”了这个事件,需要继续传递(看一下QWidget::mousePressEvent的实现,最为典型。如果希望忽略事件,只要调用父类的响应函数即可)
QEvent的accept()和ignore()一般不会用到,因为不如直接调用QWidget类的事件处理函数直接,而且作用是一样的,见下面的例子。
推荐直接调用QWidget的事件处理函数。而不是调用accept()和ignore()。
只有一种情况下,必须使用调用accept()和ignore(),那就是closeEvent(),在closeEvent()的事件处理函数中,必须调用accept()和ignore()。即如果想窗口被关闭,那么必须显示调用event->accept();如果不想关闭窗口,必须显示调用ignore(),否则窗口默认会关闭。
本章内容也是关于Qt事件。或许这一章不能有一个完整的例子,因为对于事件总是感觉很抽象,还是从底层上理解一下比较好的吧!
前面说到了事件的作用,下面来看看我们如何来接收事件。回忆一下前面的代码,我们在子类中重写了事件函数,以便让这些子类按照我们的需要完成某些功能,就像下面的代码:
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
上面的代码和前面类似,在鼠标按下的事件中检测,如果按下的是左键,做我们的处理工作,如果不是左键,则调用父类的函数。这在某种程度上说,是把事件向上传递给父类去响应,也就是说,我们在子类中“忽略”了这个事件。
比如上面的例子,eventLabel忽略了这个事件,那么这个事件就会被继续传递下去,实际上是传递给了eventLabel的父组件,QLabel,
accept()接收,表面eventLabel会处理这个事件,那么这个事件就不会再继续传递下去,那么QLabel就不会再收到这个事件,
我们可以把Qt的事件传递看成链状:如果子类没有处理这个事件,就会继续向其他类传递。
其实,Qt的事件对象都有一个accept()函数和ignore()函数。正如它们的名字,前者用来告诉Qt,事件处理函数“接收”了这个事件,不要再传递;后者则告诉Qt,事件处理函数“忽略”了这个事件,需要继续传递,寻找另外的接受者。在事件处理函数中,可以使用isAccepted()来查询这个事件是不是已经被接收了。
事实上,我们很少使用accept()和ignore()函数,而是想上面的示例一样,如果希望忽略事件,只要调用父类的响应函数即可。(其实作用是一样的)
为什么要这么做呢?因为我们无法确认父类中的这个处理函数没有操作,如果我们在子类中直接忽略事件,Qt不会再去寻找其他的接受者,那么父类的操作也就不能进行,这可能会有潜在的危险。
另外我们查看一下QWidget的mousePressEvent()函数的实现:
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
请注意第一条语句,如果所有子类(比如EventLabel类,)都没有重写mousePressEvent函数,这个事件会在这里被忽略掉,这暗示着这个组件(eventLabel)不关心这个事件,这个事件就可能被传递给其父组件。
不过,事情也不是绝对的。在一个情形下,我们必须使用accept()和ignore()函数,那就是在窗口关闭的时候。这个必须明确显示的调用accept()和ignore(),
在closeEvent()事件处理函数中,accept()是关闭窗口,ignore()是不关闭窗口,只有在closeEvent()中才是这样,
如果你在窗口关闭时需要有个询问对话框,那么就需要这么去写:
closeEvent事件的默认槽函数是QWidget类的CloseEvent()函数,该函数中,会关闭掉当前的widget,
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
bool MainWindow::continueToClose()
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
![](http://devbean.blog.51cto.com/images/editer/InBlock.gif)
这样,我们经过询问之后才能正常退出程序。
https://blog.csdn.net/zhangbinsijifeng/article/details/51577641
相关文章
- Qt常见警告问题:请更新您的工具包(Desktop Qt 5.14.1MSVC2017 64位)或为qmake选择更符合您的目标环境的mkspec
- Qt 配置文件QSettings读取以及中文问题
- qt中的进程优先级及应用内存大小设置方法,VS和Qt工程中申请超过2G的内存的方法
- QT中事件发送函数sendEvent()、postEvent()详解
- Qt对话框的事件循环分析(子线程中不能创建UI窗体分析)
- Qt中跨线程下信号和槽的使用方法
- Qt中事件循环机制详解
- Qt 之 消息机制和事件讲解
- Qt自定义事件实现及子线程向主线程传送事件消息
- QT之在QML中使用C++类和对象的两种方式
- 【QT】Qt获取前几天/后几天的时间
- 【QT】对于Qt MSVC 2017无法编译的问题解决
- Qt编写安防视频监控系统40-onvif线程处理
- Qt编写安防视频监控系统34-onvif事件订阅
- Qt开源作品17-IP地址输入控件
- qt widget设置Qt::FramelessWindowHint和Qt::WA_TranslucentBackground, 会出现一个bug: 在最小化后还原时界面停止刷新(Qt5.1解决了这个问题。但实际Qt5.7还有这个问题)
- QT in VS 多语言实现(中英文切换,每个步骤都有截图,只有UTF8才能让Qt语言家正确读取。先qApp->removeTranslator,然后installTranslator,每个类都要写上槽函数RetranslateUI)
- Qt之HTTPS登录
- Qt ------ 主事件循环与 QEventLoop
- 【转】qt ,使用tcp/ip协议网络传输数据时,字节序转换方法
- QT源码之Qt信号槽机制与事件机制的联系
- 详解 QT 源码之 Qt 事件机制原理