QML 中的全局快捷方式
Global shortcut in QML
我正在尝试在 QML (Qt 5.5) 中创建一个始终 运行 并在用户按下 alt+space
时显示的应用程序。
我试过在 QML 中使用 Action
class,但它只在 window 有焦点时有效,而不是在 window 不可见时。
我也尝试过 QShortcut(这并不理想,因为我的应用程序不是基于 QWidget 的)但是我没有结果。
当 window 不可见时,在 QApplication
上使用 eventFilter
似乎也不起作用。
有办法吗?
我从未在 QML 中实现过应用程序,但我认为您正在寻找的是全局快捷方式模块 (http://libqxt.bitbucket.org/doc/tip/qxtglobalshortcut.html)。
这是一个"A global shortcut triggers even if the application is not active."
如果系统范围的全局快捷方式是您所需要的,我不记得 Qt 有任何开箱即用的功能,更不用说 QML 了。
您将不得不求助于平台特定的 API 来完成这件事。例如 windows 上的 BOOL WINAPI RegisterHotKey()
函数。
我已经求助于使用 XGrab 并创建 QThread 的子类(因为单独的事件循环)以将其与 Qt 信号集成。
shortcutactivator.h
#ifndef SHORTCUTACTIVATOR_H
#define SHORTCUTACTIVATOR_H
#include <QThread>
class ShortcutActivator : public QThread
{
Q_OBJECT
public:
void run();
signals:
void activated();
public slots:
void end();
private:
bool terminate = false;
};
#endif // SHORTCUTACTIVATOR_H
shortcutactivator.cpp
#include "shortcutactivator.h"
#include <X11/Xlib.h>
#include <X11/Xutil.h>
void ShortcutActivator::end() {
this->terminate = true;
}
void ShortcutActivator::run() {
Display* dpy = XOpenDisplay(0);
Window root = DefaultRootWindow(dpy);
XEvent ev;
unsigned int modifiers = Mod1Mask; // AnyModifier; // ControlMask | ShiftMask | AnyModifier;
int keycode = XKeysymToKeycode(dpy,XK_space);
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);
XGrabKey(dpy, keycode, modifiers | Mod2Mask , grab_window, owner_events, pointer_mode, keyboard_mode);
XGrabKey(dpy, keycode, modifiers | LockMask, grab_window, owner_events, pointer_mode, keyboard_mode);
XGrabKey(dpy, keycode, modifiers | LockMask | Mod2Mask, grab_window, owner_events, pointer_mode, keyboard_mode);
XSelectInput(dpy, root, KeyPressMask );
while(true)
{
XNextEvent(dpy, &ev);
switch(ev.type)
{
case KeyPress:
printf("Key pressed\n");
emit this->activated();
default:
break;
}
if(this->terminate)
break;
}
XCloseDisplay(dpy);
XUngrabKey(dpy,keycode,modifiers,grab_window);
XUngrabKey(dpy,keycode,modifiers | Mod2Mask,grab_window);
XUngrabKey(dpy,keycode,modifiers| LockMask,grab_window);
XUngrabKey(dpy,keycode,modifiers | LockMask | Mod2Mask,grab_window);
}
我正在尝试在 QML (Qt 5.5) 中创建一个始终 运行 并在用户按下 alt+space
时显示的应用程序。
我试过在 QML 中使用 Action
class,但它只在 window 有焦点时有效,而不是在 window 不可见时。
我也尝试过 QShortcut(这并不理想,因为我的应用程序不是基于 QWidget 的)但是我没有结果。
当 window 不可见时,在 QApplication
上使用 eventFilter
似乎也不起作用。
有办法吗?
我从未在 QML 中实现过应用程序,但我认为您正在寻找的是全局快捷方式模块 (http://libqxt.bitbucket.org/doc/tip/qxtglobalshortcut.html)。 这是一个"A global shortcut triggers even if the application is not active."
如果系统范围的全局快捷方式是您所需要的,我不记得 Qt 有任何开箱即用的功能,更不用说 QML 了。
您将不得不求助于平台特定的 API 来完成这件事。例如 windows 上的 BOOL WINAPI RegisterHotKey()
函数。
我已经求助于使用 XGrab 并创建 QThread 的子类(因为单独的事件循环)以将其与 Qt 信号集成。
shortcutactivator.h
#ifndef SHORTCUTACTIVATOR_H
#define SHORTCUTACTIVATOR_H
#include <QThread>
class ShortcutActivator : public QThread
{
Q_OBJECT
public:
void run();
signals:
void activated();
public slots:
void end();
private:
bool terminate = false;
};
#endif // SHORTCUTACTIVATOR_H
shortcutactivator.cpp
#include "shortcutactivator.h"
#include <X11/Xlib.h>
#include <X11/Xutil.h>
void ShortcutActivator::end() {
this->terminate = true;
}
void ShortcutActivator::run() {
Display* dpy = XOpenDisplay(0);
Window root = DefaultRootWindow(dpy);
XEvent ev;
unsigned int modifiers = Mod1Mask; // AnyModifier; // ControlMask | ShiftMask | AnyModifier;
int keycode = XKeysymToKeycode(dpy,XK_space);
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);
XGrabKey(dpy, keycode, modifiers | Mod2Mask , grab_window, owner_events, pointer_mode, keyboard_mode);
XGrabKey(dpy, keycode, modifiers | LockMask, grab_window, owner_events, pointer_mode, keyboard_mode);
XGrabKey(dpy, keycode, modifiers | LockMask | Mod2Mask, grab_window, owner_events, pointer_mode, keyboard_mode);
XSelectInput(dpy, root, KeyPressMask );
while(true)
{
XNextEvent(dpy, &ev);
switch(ev.type)
{
case KeyPress:
printf("Key pressed\n");
emit this->activated();
default:
break;
}
if(this->terminate)
break;
}
XCloseDisplay(dpy);
XUngrabKey(dpy,keycode,modifiers,grab_window);
XUngrabKey(dpy,keycode,modifiers | Mod2Mask,grab_window);
XUngrabKey(dpy,keycode,modifiers| LockMask,grab_window);
XUngrabKey(dpy,keycode,modifiers | LockMask | Mod2Mask,grab_window);
}