【问题标题】:Global shortcut in QMLQML 中的全局快捷方式
【发布时间】:2016-05-25 06:51:19
【问题描述】:

我正在尝试在 QML (Qt 5.5) 中创建一个始终运行并在用户按下 alt+space 时显示的应用程序。

我曾尝试在 QML 中使用 Action 类,但它仅在窗口具有焦点时有效,在窗口不可见时无效。

我也尝试过 QShortcut(这并不理想,因为我的应用程序不是基于 QWidget)但没有结果。

当窗口不可见时,在QApplication 上使用eventFilter 似乎也不起作用。

有办法吗?

【问题讨论】:

    标签: qt qml keyboard-shortcuts qt5 qt5.5


    【解决方案1】:

    我从未在 QML 中实现过应用,但我认为您正在寻找的是全局快捷方式模块 (http://libqxt.bitbucket.org/doc/tip/qxtglobalshortcut.html)。 它是一个“即使应用程序不活动也会触发全局快捷方式”。

    【讨论】:

    • Qt5 不再支持该库。
    • 哦,是的,你是对的。为了支持 qt5,github 上有一个可用的库(github.com/ddqd/qxtglobalshortcut5 至少使用 qt5.4 进行了测试)。但无论如何,对于操作系统来说,这可能是一项工作
    【解决方案2】:

    如果您需要一个系统范围的全局快捷方式,我不记得 Qt 有任何开箱即用的功能,更不用说 QML。

    您将不得不求助于平台特定的 API 来完成这项工作。例如,在 Windows 上使用 BOOL WINAPI RegisterHotKey() 函数。

    【讨论】:

    • 但是当窗口不可见时我需要快捷方式工作,所以没有焦点。
    【解决方案3】:

    我已经求助于使用 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);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-19
      • 1970-01-01
      • 2018-10-18
      • 2015-04-28
      相关资源
      最近更新 更多