Details
-
Bug
-
Resolution: Done
-
P2: Important
-
5.4.2, 5.10.1
-
None
-
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.