QEvent的accept()和ignore()一般不会用到,因为不如直接调用QWidget类的事件处理函数直接,而且作用是一样的,见下面的例子。

推荐直接调用QWidget的事件处理函数。而不是调用accept()和ignore()。

只有一种情况下,必须使用调用accept()和ignore(),那就是closeEvent(),在closeEvent()的事件处理函数中,必须调用accept()和ignore()。即如果想窗口被关闭,那么必须显示调用event->accept();如果不想关闭窗口,必须显示调用ignore(),否则窗口默认会关闭。

本章内容也是关于Qt事件。或许这一章不能有一个完整的例子,因为对于事件总是感觉很抽象,还是从底层上理解一下比较好的吧!

前面说到了事件的作用,下面来看看我们如何来接收事件。回忆一下前面的代码,我们在子类中重写了事件函数,以便让这些子类按照我们的需要完成某些功能,就像下面的代码:

void MyLabel::mousePressEvent(QMouseEvent *event)
{
        if(event->button() == Qt::LeftButton) {
                // do something
        }else {
                QLabel::mousePressEvent(event);
        }
}

上面的代码和前面类似,在鼠标按下的事件中检测,如果按下的是左键,做我们的处理工作,如果不是左键,则调用父类的函数。这在某种程度上说,是把事件向上传递给父类去响应,也就是说,我们在子类中“忽略”了这个事件。

比如上面的例子,eventLabel忽略了这个事件,那么这个事件就会被继续传递下去,实际上是传递给了eventLabel的父组件,QLabel,

accept()接收,表面eventLabel会处理这个事件,那么这个事件就不会再继续传递下去,那么QLabel就不会再收到这个事件,

我们可以把Qt的事件传递看成链状:如果子类没有处理这个事件,就会继续向其他类传递。

其实,Qt的事件对象都有一个accept()函数和ignore()函数。正如它们的名字,前者用来告诉Qt,事件处理函数“接收”了这个事件,不要再传递;后者则告诉Qt,事件处理函数“忽略”了这个事件,需要继续传递,寻找另外的接受者。在事件处理函数中,可以使用isAccepted()来查询这个事件是不是已经被接收了。

事实上,我们很少使用accept()和ignore()函数,而是想上面的示例一样,如果希望忽略事件,只要调用父类的响应函数即可。(其实作用是一样的)

为什么要这么做呢?因为我们无法确认父类中的这个处理函数没有操作,如果我们在子类中直接忽略事件,Qt不会再去寻找其他的接受者,那么父类的操作也就不能进行,这可能会有潜在的危险。

另外我们查看一下QWidget的mousePressEvent()函数的实现:

void QWidget::mousePressEvent(QMouseEvent *event)
{
        event->ignore();//QWidget 会忽略这个事件,
        if ((windowType() == Qt::Popup)) {
                event->accept();
                QWidget* w;
                while ((w = qApp->activePopupWidget()) && w !=this){
                        w->close();
                        if (qApp->activePopupWidget() == w)// widget does not want to dissappear
                                w->hide();// hide at least
                }
                if (!rect().contains(event->pos())){
                        close();
                }
        }
}

请注意第一条语句,如果所有子类(比如EventLabel类,)都没有重写mousePressEvent函数,这个事件会在这里被忽略掉,这暗示着这个组件(eventLabel)不关心这个事件,这个事件就可能被传递给其父组件。

不过,事情也不是绝对的。在一个情形下,我们必须使用accept()和ignore()函数,那就是在窗口关闭的时候。这个必须明确显示的调用accept()和ignore(),

在closeEvent()事件处理函数中,accept()是关闭窗口,ignore()是不关闭窗口,只有在closeEvent()中才是这样,

如果你在窗口关闭时需要有个询问对话框,那么就需要这么去写:

closeEvent事件的默认槽函数是QWidget类的CloseEvent()函数,该函数中,会关闭掉当前的widget,

void MainWindow::closeEvent(QCloseEvent *event)
{
        if(continueToClose()) {
                event->accept();
        }else {
                event->ignore();
        }
}

bool MainWindow::continueToClose()
{
        if(QMessageBox::question(this,
                                            tr("Quit"),
                                            tr("Are you sure to quit this application?"),
                                            QMessageBox::Yes | QMessageBox::No,
                                            QMessageBox::No)
                == QMessageBox::Yes) {
                returntrue;
        }else {
                return false;
        }
}

这样,我们经过询问之后才能正常退出程序。

https://blog.csdn.net/zhangbinsijifeng/article/details/51577641

accept()函数用来告诉Qt,事件处理函数“接收”了这个事件,不要再传递;ignore()函数则告诉Qt,事件处理函数“忽略”了这个事件,需要继续传递(看一下QWidget::mousePressEvent的实现,最为典型。如果希望忽略事件,只要调用父类的响应函数即可)的更多相关文章

  1. Qt 学习之路 2(19):事件的接受与忽略(当重写事件回调函数时,时刻注意是否需要通过调用父类的同名函数来确保原有实现仍能进行!有好几个例子。为什么要这么做?而不是自己去手动调用这两个函数呢?因为我们无法确认父类中的这个处理函数有没有额外的操作)

    版本: 2012-09-29 2013-04-23 更新有关accept()和ignore()函数的相关内容. 2013-12-02 增加有关accept()和ignore()函数的示例. 上一章我们 ...

  2. one(type,[data],fn) 为每一个匹配元素的特定事件(像click)绑定一个一次性的事件处理函数。

    one(type,[data],fn) 概述 为每一个匹配元素的特定事件(像click)绑定一个一次性的事件处理函数. 在每个对象上,这个事件处理函数只会被执行一次.其他规则与bind()函数相同.这 ...

  3. cocos2dx 3.x(获得父类的node型指针调用父类函数this->getParent())

    void CenterLayer::zhanzheng(CCObject* pSender){ ((GameScene*)this->getParent())->showLayer(Gam ...

  4. 23.C++- 继承的多种方式、显示调用父类构造函数、父子之间的同名函数、virtual虚函数

     上章链接: 22.C++- 继承与组合,protected访问级别 继承方式 继承方式位于定义子类的”:”后面,比如: class Line : public Object //继承方式是publi ...

  5. C++/JAVA/C#子类调用父类函数情况[留存]

    时间久了就容易记不清了,特留存备用查看 c++ 1.构造函数调用   常用初始化列表  或者显示调用 1.1同一个类中构造函数调用构造函数   尽量不要这样做,因为结果不确定!避免麻烦(C++11增加 ...

  6. TP5:使用了INPUT函数来接收参数了,还需再过滤SQL注入吗

    TP5:使用了INPUT函数来接收参数了,还需再过滤SQL注入吗,默认的INPUT函数都做了哪些动作啊 有了PDO参数绑定 基本上不需要考虑sql注入的问题(除非自己拼接SQL),需要考虑的是XSS方 ...

  7. GObject调用父类函数

    最近在分析Gstreamer的代码时,发现GstPipeline中有如下代码: result = GST_ELEMENT_CLASS (parent_class)->change_state ( ...

  8. python super()函数:调用父类的构造方法

    python子类会继承父类所有的类属性和类方法.严格来说,类的构造方法其实就是实例方法,因此,父类的构造方法,子类同样会继承. 我们知道,python是一门支持多继承的面向对象编程语言,如果子类继承的 ...

  9. c++虚函数、子类中调用父类方法

    全部 代码: 1 #include<stdio.h> 2 #include<string.h> 3 #include<iostream> 4 #include< ...

随机推荐

  1. 【HDU 6008】Worried School(模拟)

    Problem Description You may already know that how the World Finals slots are distributed in EC sub-r ...

  2. 相应缓存设置HttpCacheability 枚举

      成员名称 说明   NoCache 设置 Cache-Control: no-cache 标头.如果没有字段名,则指令应用于整个请求,且在满足请求前,共享(代理服务器)缓存必须对原始 Web 服务 ...

  3. CentOS6 CentOS7 yum安装图形界面

    CentOS6 yum安装图形界面yum groupinstall -y "Desktop" "Desktop Platform" "Desktop ...

  4. SeLion数据驱动中遇到的问题,以及解决方案

    问题描述: 使用selion框架数据驱动时,总是test ignored. 解决方案: 把这个dataprovider方法拿出来做单元测试.有详细报错. 问题1:使用wps保存,poi包只能解析xls ...

  5. 使用windows操作EXCEL如何关闭EXCEL进程

    经常项目上有导入excel的需求,其实导入一个固定格式的excel数据非常容易,但是,发现一个问题就是,导入excel后,用户在打开excel时,必须要打开2次才能打开excel,这让人很不爽:开始查 ...

  6. 移动web页面字体大小二

    按设计稿中的字体大小设置页面字体大小(px),在手机端,因为不同设备会有不同,换算成rem单位.rem是“font size of the root element”,可以通过这篇文章了解http:/ ...

  7. WordPress 权限方案

    每个主机和主机的情况可能有所差异,如下只是概括性地描述,并不一定适用于所有情况.它只适用于进行“常规设置”的情况(注:比如通过“suexec”方式来进行共享主机的,详情见下方) 通常,所有文件是由您的 ...

  8. UVAlive 3026 KMP 最小循环节

    KMP算法: 一:next数组:next[i]就是前面长度为i的字符串前缀和后缀相等的最大长度,也即索引为i的字符失配时的前缀函数. 二:KMP模板 /* pku3461(Oulipo), hdu17 ...

  9. [Bzoj1083][SCOI2005]互不侵犯king(状压dp)

    1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4595  Solved: 2664[Submit][ ...

  10. zmq.error.ZMQError: Address already in use

    1.如下代码,启动的时候python app.py会报如题的错误 app.py #!/user/bin python # -*- coding:utf-8 -*- import os from dat ...