据我所见,@SamVarshavchik 指出libkeybinder 在后台使用libx11,因此您可以使用libx11 来摆脱GTK 事件循环不是很友好Qt。 AFAIK KDE 的 KAction 对其全局短键使用相同的技术,所以我认为这种技术可以很好地与 Qt 的事件循环配合使用。
说了这么多,你可以使用here提供的热键示例:
x11_hot_key.pro:
#-------------------------------------------------
#
# Project created by QtCreator 2015-05-04T01:47:22
#
#-------------------------------------------------
QT += core
QT -= gui
TARGET = x11_hot_key
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp
CONFIG += link_pkgconfig
PKGCONFIG += x11
main.cpp:
#include <QCoreApplication>
#include <iostream>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
using namespace std;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Display* dpy = XOpenDisplay(0);
Window root = DefaultRootWindow(dpy);
XEvent ev;
unsigned int modifiers = ControlMask | ShiftMask;
int keycode = XKeysymToKeycode(dpy,XK_Y);
Window grab_window = root;
Bool owner_events = False;
int pointer_mode = GrabModeAsync;
int keyboard_mode = GrabModeAsync;
XGrabKey(dpy, keycode, modifiers, grab_window, owner_events, pointer_mode,
keyboard_mode);
XSelectInput(dpy, root, KeyPressMask );
while(true)
{
bool shouldQuit = false;
XNextEvent(dpy, &ev);
switch(ev.type)
{
case KeyPress:
cout << "Hot key pressed!" << endl;
XUngrabKey(dpy,keycode,modifiers,grab_window);
shouldQuit = true;
default:
break;
}
if(shouldQuit)
break;
}
XCloseDisplay(dpy);
return a.exec();
}
或者您也可以使用this simple library 所提供的here,它还有一些简单的示例以及方便的Makefile 供您使用。
由于我不知道XGrabKey 的异步通信者,您将遇到的一个问题是while(true) 循环永远不会返回并阻塞主线程因此应用程序因此您想要将其移入一个单独的线程并使用signals 和slots 将其连接到主线程。不过,这应该不是什么大问题,也不会影响您的应用程序的性能,因为 AFAIK XNextEvent 会阻塞直到您的键被击中,因此处理器不会进行无用的处理...
希望这会有所帮助。