[SOLVED] QWidget::eventFilter() not catching key combinations



  • Hello,

    I posted this on qt-center but haven't gotten any takers. I have a multitab application that implements a main widget on each tab that's added. Within each widget is a QTextEdit. For some reason, the QTextEdit is not capturing a "Ctrl+C" key sequence through QAction's shortcut. So I installed an eventFilter in the object's constructor to attach to the QTextEdit. The object's code (simplified) is:

    @
    TabObject::TabObject(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::TabObject)
    {
    ui->setupUi(this);
    ui->myTextEdit->installEventFilter(this);
    }

    bool TabObject::eventFilter(QObject *obj, QEvent *event)
    {
        if (obj == ui->myTextEdit) {
     
                     if (event->type() == QEvent::KeyPress) {
                              QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
                              qDebug()<<"key is: "<<keyEvent->key();
                              qDebug()<<"key type is: "<<keyEvent->type();
                               if (keyEvent->matches(QKeySequence::Copy)){
                                          qDebug()<<"copy sequence entered...";
                                           ui->myTextEdit->copy();
                                          return true;
                               }
                              return false;
                      } else {
                               return false;
                              }
            } else {
                  return TabObject::eventFilter(obj, event);
                     }
    

    }
    @

    What happens with the qDebug() output is that it picks up on the CTRL key being pressed but, while CTRL is being held down, it doesn't pick up on C, so the "copy sequence entered..." is not being outputted. I have this same eventfilter procedure installed on a popup window that inherits QMainWindow and that debug output doesn't pick up on CTRL, but picks up on C and the CTRL+C key sequence hits appropriately.

    Now, as I said, this is a multitab app built using QMainWindow that, when a new tab is to be created, executes:

    @
    TabObject *tabObject = new TabObject;
    mainTabWidget->addTab(tabObject)
    @

    The MainWindow reimplements QMainWindow::keyPressEvent() as follows, so that when the user presses ENTER or RETURN, a new tab is created:

    @ void MainWindow::keyPressEvent( QKeyEvent* e )
    {
    switch( e->key() )
    {
    case Qt::Key_Enter:
    case Qt::Key_Return:
    // ** Code to open new tab **//
    break;
    default:
    ;
    }
    QMainWindow::keyPressEvent( e );
    }
    @

    So I really have a couple of questions:

    1. Could this keyPressEvent() reimplementation be intercepting or confusing the eventfilter attached to the QTextEdit in the implemented object?

    2. Does the eventFilter for QMainWindow and QWidget behave differently? As I mentioned above, it seems to be working for a popup window that inherits QMainWindow, and ignores the Control key, but seems to be the opposite for the QObject.

    Any guidance you can provide would be very helpful and appreciated.

    Thanks!


  • Moderators

    [quote author="kewljohny" date="1385092711"]

    1. Could this keyPressEvent() reimplementation be intercepting or confusing the eventfilter attached to the QTextEdit in the implemented object?
      [/quote]
      eventFilters() kick in before the event handlers are called. So the handlers cannot interfer the eventFilters.
      [quote author="kewljohny" date="1385092711"]
    2. Does the eventFilter for QMainWindow and QWidget behave differently? As I mentioned above, it seems to be working for a popup window that inherits QMainWindow, and ignores the Control key, but seems to be the opposite for the QObject.
      [/quote]
      eventFilter() is defined on QObject and behaves for all instances the same.

    What you can do is to additionally check for the event type QEvent::ShortcutOverride. You can safely add it to your existing check:
    @
    bool TabObject::eventFilter(QObject *obj, QEvent *event)
    {
    if (obj == ui->myTextEdit) {

                     if (event->type() == QEvent::KeyPress || event->type() == QEvent::ShortcutOverride) {
                              QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
                              .....
                      } else {
                               return false;
                              }
            } else {
                  return TabObject::eventFilter(obj, event);
                     }
    

    }
    @
    This is a quick check if the shortcut interfers with another shortcut in the same scope.



  • That's amazing. Simply adding the event->type == QEvent::ShortcutOverride statement in there fixed the issue and the CTRL+C hits in the child. I take that OR condition out, and it doesn't hit. Thank you so much for this! It was driving me nuts!!


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.