Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-66809

QShortcut ignores DeferredDelete event

    XMLWordPrintable

Details

    • a42a4513398a159e4f6749fbcb1309c4a42b4841 (qt/qtbase/5.12)

    Description

      It is imposible to delete QShortcut using deleteLater() method.

      It looks like it overrides QObject::event() method and does not call the base class implementation. Maybe it has been done on purpose.

       

      Here is the code of QShortcut::event():

      bool QShortcut::event(QEvent *e)
      {
          Q_D(QShortcut);
          bool handled = false;
          if (d->sc_enabled && e->type() == QEvent::Shortcut) {
              QShortcutEvent *se = static_cast<QShortcutEvent *>(e);
              if (se->shortcutId() == d->sc_id && se->key() == d->sc_sequence){
      #if QT_CONFIG(whatsthis)
                  if (QWhatsThis::inWhatsThisMode()) {
                      QWhatsThis::showText(QCursor::pos(), d->sc_whatsthis);
                      handled = true;
                  } else
      #endif
                  if (se->isAmbiguous())
                      emit activatedAmbiguously();
                  else
                      emit activated();
                  handled = true;
              }
          }
          return handled;
      }
      
      

      The easiest way to reproduce the bug is as follows:

      Widget::Widget(QWidget *parent) :
          QWidget(parent),
          ui(new Ui::Widget)
      {
          ui->setupUi(this);
      
          QShortcut *shortcut = new QShortcut(QKeySequence("Ctrl+A"), this);
          QObject::connect(shortcut, &QShortcut::activated, [shortcut] () {
              qDebug() << "Shortcut activated: " << shortcut->key().toString();
              shortcut->deleteLater();
          });
      }
      
      Widget::~Widget()
      {
          delete ui;
      }
      

      Press Ctrl+A several times and you'll see that QShortcut still works despite of deleteLater() call.
      It is easier to test with lambda, but the issue is the same with slots.

      How to fix this.
      The easiest way is to add QObject::event(e) at the end of QShortcut::event(). But maybe it won't be an appropriate fix if it filters events of other object.

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            qt.team.quick.subscriptions Qt Quick and Widgets Team
            adyakonov Arkady Dyakonov
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes