我在Qt
中使用GNU/Linux
创建了一个应用程序,然后在后台运行。我想在用户按某些组合键时执行某些应用程序功能,例如Ctrl
+ Alt
+ A
...
我知道这是可能的,Gnome Pie会这样做,但我不知道如何捕获密钥。我尝试使用此问题中提供的examples但它们都没有用...我也不想以root身份运行我的应用程序...
有人能指出一些资源或给我一些提示吗?
修改
@iharob建议我应该使用libkeybinder
。我找到了它,尝试了它,但它使用了GTK
而GTK
与Qt
的效果不佳......我甚至不是GTK
初学者,从未使用过它,但我认为GTK
事件循环与Qt
事件循环冲突;当我从回调中发出Qt
信号时,在按下该键后调用该信号(也在调用gtk_init
之后),应用程序崩溃。
如果我可以在按下键盘组合键时创建一个发出信号的类(例如Ctrl+Alt+A
),那将是多么美妙。
答案 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
会阻塞,直到您的密钥被命中,因此处理器不会无用处理......
希望这有帮助。