Vii
Vii

Reputation: 841

Qt / C++ - Monitor specified input without focus

I want to be able to press a specific Qt::Key at any time regardless of focus. For example, ctrl+shift+F activates a method that brings the window back into focus.

I've done google searches for how to monitor input without focus in qt but I can't find anything.

Upvotes: 4

Views: 2429

Answers (4)

Łukasz Kosiński
Łukasz Kosiński

Reputation: 1

It is possible to detect a pressed key outside the window. You only need to use the built-in Windows libraries. You can read how to do it in this article. Unfortunately, it's not that simple on the Unix systems currently.

Upvotes: -1

Vii
Vii

Reputation: 841

Found the answer here after further searching: http://qt-project.org/forums/viewthread/35192

I didn't know they were referring to as 'global' hotkeys so I was essentially describing in google search.

I will elaborate since the code linked there isn't accurate (had to tweak a lot).

This is my current code:

#define MOD_NOREPEAT 0x4000
#define MOD_CTRL 0x0002
#define MOD_ALT 0x0001
#define MOD_SHIFT 0x0004

int main(int argc, char *argv[])
{
    RegisterHotKey(NULL, 1, MOD_ALT | MOD_SHIFT | MOD_NOREPEAT, 0x46);

    QApplication a(argc, argv);
    Interface w;
    w.show();

    a.processEvents();

    MSG msg;
    while(GetMessage(&msg, NULL, 0, 0))
    {
        if(w.isClosing)
            return msg.wParam;
        TranslateMessage(&msg);
        DispatchMessage(&msg);
        if(msg.message == WM_HOTKEY)
        {
            if(msg.wParam == 1)
                qDebug() << "Hot Key activated: HOME";
        }
    }

    return msg.wParam;
}

The a.processEvents will make your QApplication continue processing events regardless of the while loop. When I exited the program it wouldn't kill because of the loop running in main, so now I check for a bool from the Interface class that overrides closeEvent as such: void closeEvent(QCloseEvent *);

And in class file:

void Interface::closeEvent(QCloseEvent *)
{
    isClosing = true;
}

The only downside is hex codes for hotkeys. If anyone has a solution please let me know. 0x46 is F.

Upvotes: 2

Nejat
Nejat

Reputation: 32665

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 or hidden.

After compiling Qxt, link your application to it by adding these to your .pro :

CONFIG += qxt
QXT = core gui

And include QxtGlobalShortcut :

#include <QxtGlobalShortcut>

Example usage :

QxtGlobalShortcut* shortcut = new QxtGlobalShortcut(window);
connect(shortcut, SIGNAL(activated()), window, SLOT(toggleVisibility()));
shortcut->setShortcut(QKeySequence("Ctrl+Shift+F"));

Upvotes: 2

Jeremy Friesner
Jeremy Friesner

Reputation: 73171

You can do this either by subclassing QApplication and overriding its event(QEvent *) method, or (more commonly) by calling qApp->installEventFilter(someObject), where (someObject) is some Qt object (whichever one is most convenient for you) whose eventFilter(QObject *, QEvent *) method you have overridden with your own implementation that watches for the appropriate QKeyEvent and does the appropriate action in response.

Upvotes: 5

Related Questions