zoukankan      html  css  js  c++  java
  • QDialog之屏蔽Esc键(简单深刻,要么重写keyPressEvent然后break忽略此事件,要么重写eventFilter然后return,都是为了忽略此事件)

    简述

    Qt中Esc键会在一些控件中默认的进行一些事件的触发,比如:QDialog,按下Esc键窗口消失。大多数情况下,我们不需要这么做,那么就需要对默认事件进行屏蔽。

    源码分析

    通过查看QDialog的源码,我们很容易会发现keyPressEvent事件中,当按下Esc键时,会默认执行reject()。

    void QDialog::keyPressEvent(QKeyEvent *e)
    {
        //   Calls reject() if Escape is pressed. Simulates a button
        //   click for the default button if Enter is pressed. Move focus
        //   for the arrow keys. Ignore the rest.
    #ifdef Q_OS_MAC
        if(e->modifiers() == Qt::ControlModifier && e->key() == Qt::Key_Period) {
            reject();
        } else
    #endif
        if (!e->modifiers() || (e->modifiers() & Qt::KeypadModifier && e->key() == Qt::Key_Enter)) {
            switch (e->key()) {
            case Qt::Key_Enter:
            case Qt::Key_Return: {
                QList<QPushButton*> list = findChildren<QPushButton*>();
                for (int i=0; i<list.size(); ++i) {
                    QPushButton *pb = list.at(i);
                    if (pb->isDefault() && pb->isVisible()) {
                        if (pb->isEnabled())
                            pb->click();
                        return;
                    }
                }
            }
            break;
            case Qt::Key_Escape:
                reject();
                break;
            default:
                e->ignore();
                return;
            }
        } else {
            e->ignore();
        }
    }

    Ok,我们如果想改变Esc键的默认动作,则可以通过两种途径:

    1. 重写Esc键对应的事件

    2. 重写reject()

    事件过滤器

    对QDialog使用事件过滤器,过滤Esc键。

    installEventFilter(new EventFilter(this));

    bool EventFilter::eventFilter(QObject *obj, QEvent *event)
    {
        QDialog *pDialog = qobject_cast<QDialog *>(obj);
        if (pDialog != NULL)
        {
            switch (event->type())
            {
            case QEvent::KeyPress:
            {
                QKeyEvent *pKeyEvent = static_cast<QKeyEvent*>(event);
                if (pKeyEvent->key() == Qt::Key_Escape)
                {
                    return true;
                }
            }
            }
        }
        return QObject::eventFilter(obj, event);
    }

    事件重写

    重写QDialog的键盘事件keyPressEvent。

    void Dialog::keyPressEvent(QKeyEvent *event)
    {
        switch (event->key())
        {
        case Qt::Key_Escape:
            break;
        default:
            QDialog::keyPressEvent(event);
        }
    }

    重写reject

    m_bClosed为关闭的条件,为true时,窗口才会关闭。

    void Dialog::reject()
    {
        if (m_bClosed)
            QDialog::reject();
    }

    关于事件过滤器和事件重写其实是属于一种情况,都是基于事件判断和过滤的,而事件过滤器相对来说更易用、扩展性更好,不需要针对每个控件都去重写对应的事件。

    http://blog.csdn.net/liang19890820/article/details/50357323

  • 相关阅读:
    提高网站访问速度的34条军规(7-10)
    指针与函数传参的思考
    提高网站访问速度的34条军规(11-13)
    [置顶] 程序员面试之道(《程序员面试笔试宝典》)之如何回答技术性的问题?
    CentOS6.4 编译安装Python 3.3.2
    hdu 4055 Number String(有点思维的DP)
    解读ASP.NET 5 & MVC6系列(4):核心技术与环境配置
    解读ASP.NET 5 & MVC6系列(6):Middleware详解
    解读ASP.NET 5 & MVC6系列(5):Configuration配置信息管理
    解读ASP.NET 5 & MVC6系列(7):依赖注入
  • 原文地址:https://www.cnblogs.com/findumars/p/6919596.html
Copyright © 2011-2022 走看看