27

I've got a simple Qt app, and I just want to respond to the F12 key, regardless of which widget has focus.

Is there some easy signal or something I can hook in to?

I want to use the F12 key to toggle the main window fullscreen on/off.

Jasper
  • 2,166
  • 4
  • 30
  • 50
sidewinderguy
  • 2,394
  • 4
  • 24
  • 24
  • Be sure to let the user configure that. There are several other programs that have that exact same feature. – Falmarri Dec 03 '10 at 00:44
  • Falmarri: not sure what you mean. Do you mean to let the user decide which hotkey to use to toggle fullscreen mode? Thx. – sidewinderguy Dec 03 '10 at 00:46

3 Answers3

32

I haven't tried, but here is what I would do :

Create a QShortcut and make sure its context (with setContext()) is Qt::ApplicationShortcut.

shortcut = new QShortcut(QKeySequence(Qt::Key_F12), parent);
shortcut->setContext(Qt::ApplicationShortcut);

Then you just need to connect a slot to the QShortcut::activated() signal.

satanas
  • 706
  • 7
  • 11
Jérôme
  • 26,567
  • 29
  • 98
  • 120
  • This is one of those things where once you see how to do it, it seems obvious. But before you showed me, I had no clue. ;-) – sidewinderguy Dec 03 '10 at 19:40
  • It seems to also be easier to use widget wide shortcuts than filtering QKeyEvents – Max13 Mar 03 '15 at 06:42
  • 3
    `parent` must be a pointer to existing widget. One can pass `QApplication::desktop()` as `parent`. It is worth to know that modal windows will block shortcuts even with application context. – Marcin Jun 22 '16 at 14:17
3

Setting the shortcut context to Qt::ApplicationShortcut has a serious flaw. It will not work in modal dialogs. So if you want a trully real pan-application-wide shortcut, then you need to override application's notify() method. The alternative is to install event filter for the application object but that I suspect would be slower and requires slightly more code. With notify() it is very simple:

class MyApplication : public QApplication
{
    // TODO: constructor etc.

protected:

bool MyApplication::notify(QObject *receiver, QEvent *event) override
{
    if (event->type() == QEvent::KeyPress)
    {
        auto keyEvent = static_cast<QKeyEvent*>(event);
        if (keyEvent->key() == Qt::Key_F12 && keyEvent->modifiers() == Qt::NoModifiers)
        {
            // TODO: do what you need to do
            return true;
        }  
    }
    return QApplication::notify(receiver, event);
}

}
2

If you have a "central widget" which all of the other widgets are children of, then you can simply set that as the widget argument for QShortcut.

(Python, qt5)

self.centralwidget = QtWidgets.QWidget(MainWindow)

QtWidgets.QShortcut(QtGui.QKeySequence("F12"), self.centralwidget, self.goFullScreen)

I added this as an answer because the shortcut context flag: Qt.ApplicationShortcut did not work for me.

Prof
  • 657
  • 1
  • 14
  • 24