PDA

View Full Version : QAction with Escape shortcut (Qt::Key_Escape)



serget
21st January 2012, 15:04
Hi,

I'm implementing a context menu in QWidget derived class and I want an action to be triggered by Escape shortcut, so I set a shortcut when I create QAction:


m_clearBlockAction = new QAction(tr("Clear selection"), this);
m_clearBlockAction->setShortcut(tr("Esc"));
addAction(m_clearBlockAction);

The problem is shortcut does not work and even more - it intercepts (or does not allow to fire) key stroke events, i.e. even if I put direct handling into event filter, it does not catch Qt::Key_Escape code:


bool WidgetCtrl::event(QEvent *e)
{
if (e->type() == QEvent::KeyPress)
{
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(e);

if (keyEvent->key() == Qt::Key_Escape)
{
qDebug() <<"ESC";
}
}
}

qDebug() <<"ESC" is never gets executed; once I remove shortcut from action, event code works.


Any help?
Thanks
Serge T

blueSpirit
21st January 2012, 15:49
This is how I would solve your problem:

QAction* pAction = new QAction( "text4ESC", this );
pAction->setShortcut( Qt::Key_Escape );
pAction->setShortcutContext( Qt::WindowShortcut );
connect( pAction, SIGNAL(triggered()),
this, SLOT(SL_DoSomething()) );
addAction( pAction );

setContextMenuPolicy( Qt::ActionsContextMenu );If you add this to the constructor of your widget, it should work. I guess the shortcut context is important...

To solve the problem with the event() method, you could install an event filter on all widgets - since (I guess) the focus widget gets the key events first, and if it accepts them, they were not forwarded to the parent widgets.

serget
21st January 2012, 16:34
Thank you for your reply. Actually it was my inattention - the slot DID was called by the trigger, no problem. However, what confused me is the fact that both event() and keyPressedEvent() stop receiving Esc once I assigned an action shortcut to it. I expected event() to always process all keystrokes.

As for ShortcutContext, it is not necessary to set since it is Qt::WindowShortcut alreadty by default.

Serge T