Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect global key sequence press in Qt?

Tags:

c++

windows

qt

I want to detect whether a key sequence is pressed and want to perform certain task on that event in Qt. Currently I can detect keypresses for certain widgets but how to detect global keypresses. By global I mean that even if the application is minimized or hidden , it should detect key press.

I tried making an eventFilter for the application, by first overloading QObject::eventFilter like this:

bool GlobalEventFilter::eventFilter(QObject *Object, QEvent *Event)
{
  if (Event->type() == QEvent::KeyPress)
  {
    QKeyEvent *KeyEvent = (QKeyEvent*)Event;

    switch(KeyEvent->key())
    {
      case Qt::Key_F1:
        cout<<"F1 press detected"<<endl;
        return true;
      default:
        break;
    }
  }
  return QObject::eventFilter(Object,Event);
}

and then installing that object as the eventFilter for my application:

QApplication a(argc,argv);
a.installEventFilter(new GlobalEventFilter());

and I also tried the doing this:

QCoreApplication::instance()->installEventFilter(new GlobalEventFilter());

In both the cases I am able to detect key presses when my application window is open but it fails when window is minimized or hidden. How to solve this?

like image 780
user221458 Avatar asked Apr 21 '14 07:04

user221458


2 Answers

See the documentation of QKeyEvent:

Key events are sent to the widget with keyboard input focus when keys are pressed or released.

That means, if you wish to use QKeyEvent, you need to have the keyboard focus. Filtering those events does not change this conceptually either. I am not sure where you got the filtering idea from.

You might want to look into alternative solutions, for instance how it is implemented in kwin, etc. In general, be careful with this use case. It could do weird things without the end users noticing it.

You could take a look at this class:

QxtGlobalShortcut Class Reference

You could write something like this then:

main.cpp

#include <QxtGlobalShortcut>

#include <QApplication>
#include <QMainWindow>
#include <QDebug>

class MyGlobalShortcutHandler : public QObject
{
    Q_OBJECT
public:
    explicit MyGlobalShortcutHandler(QObject *parent = 0)
        : QObject(parent)
    {
        m_globalShortcut.setShortcut(QKeySequence("Ctrl+Shift+X"));
        m_globalShortcut.setEnabled(true);

        connect(&m_globalShortcut, SIGNAL(activated()), SLOT(handleGlobalShortcut()));
    }

public slots:
    void handleGlobalShortcut()
    {
        qDebug() << "Global shortcut handled";
    }

private:
    QxtGlobalShortcut m_globalShortcut;
};

#include "main.moc"

int main(int argc, char **argv)
{
    QApplication application(argc, argv);
    QMainWindow mainWindow;
    MyGlobalShortcutHandler myGlobalShortcut();
    mainWindow.show();
    return application.exec();
}

main.pro

TEMPLATE = app
TARGET = main
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += qxt
QXT = core gui
SOURCES += main.cpp

Build and Run

qmake-qt4 && make && ./main

This code should be working with Qt 4, at least. It prints out the debug statement for me. You could easily verify this on your end.

To get the libqxt library, please visit the following link:

http://dev.libqxt.org/libqxt/wiki/Home

like image 140
lpapp Avatar answered Oct 13 '22 02:10

lpapp


This feature is not implemented in Qt. You can use Qxt. Qxt is an extension library for Qt providing a suite of cross-platform utility classes to add functionality not readily available in Qt. It has Global Shortcut (hot keys) which detects key presses even if the application is minimized.

After compiling and linking your application to Qxt, you can include QxtGlobalShortcut:

#include <QxtGlobalShortcut>

Example usage:

QxtGlobalShortcut* shortcut = new QxtGlobalShortcut(window);
connect(shortcut, SIGNAL(activated()), window, SLOT(toggleVisibility()));
shortcut->setShortcut(QKeySequence("Ctrl+Shift+F12"));
like image 44
Nejat Avatar answered Oct 13 '22 03:10

Nejat