使用GNU / Linux中的键盘快捷方式启动应用程序功能

时间:2015-04-28 20:34:32

标签: c++ c linux qt keyboard-events

我在Qt中使用GNU/Linux创建了一个应用程序,然后在后台运行。我想在用户按某些组合键时执行某些应用程序功能,例如Ctrl + Alt + A ...

我知道这是可能的,Gnome Pie会这样做,但我不知道如何捕获密钥。我尝试使用此问题中提供的examples但它们都没有用...我也不想以root身份运行我的应用程序...

有人能指出一些资源或给我一些提示吗?

修改

@iharob建议我应该使用libkeybinder。我找到了它,尝试了它,但它使用了GTKGTKQt的效果不佳......我甚至不是GTK初学者,从未使用过它,但我认为GTK事件循环与Qt事件循环冲突;当我从回调中发出Qt信号时,在按下该键后调用该信号(也在调用gtk_init之后),应用程序崩溃。

如果我可以在按下键盘组合键时创建一个发出信号的类(例如Ctrl+Alt+A),那将是多么美妙。

1 个答案:

答案 0 :(得分:2)

据我所知, @SamVarshavchik 指出libkeybinder在后​​台使用libx11所以你可以使用libx11来摆脱GTK事件循环不是很Qt友好的。 AFAIK KDE的{​​{1}}对其全局快捷键使用了相同的技术,所以我认为这种技术可以很好地适应KAction的事件循环。

如上所述,您可以使用提供here的热键示例:

<强> x11_hot_key.pro:

Qt

<强> main.cpp中:

#-------------------------------------------------
#
# 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

或者您可以使用this simple library作为呈现的here,其中还有一些简单的示例和一个方便的#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(); } 供您使用。

由于我不了解Makefile的异步通信对象,您将遇到的问题是XGrabKey循环永远不会返回并阻塞主线程因此应用程序所以您想要的是在单独的线程中移动它并使用while(true)signals将其连接到主线程。这应该不是一个大问题,并且不会影响应用程序的性能,因为AFAIK slots会阻塞,直到您的密钥被命中,因此处理器不会无用处理......

希望这有帮助。