pch.h 的路径加入设置的 include_QT跨平台设置全局热键的方法

1a47b627d3bdfc32c52c6a8848d33733.png

前言

之间做待办列表的时候提过全局热键的功能,当时说后面会单独讲解跨平台设置全局热键的方法,今天就来兑现当时的承诺。话不多说,先来看一下实现效果:

9fdd8e2fcf8dfd03c9091ff4cfb4b072.gif

QxtGlobalShortcut和QHotkey介绍

因为要想实现全局热键功能,无非要对按键事件进行过滤并处理,但是不同平台过滤和处理的方法又不同,所以对系统底层事件了解不是很清楚的话,自己实现起来就很有难度。而且很多人都觉得我就只是想添加一个全局热键而已,没必要那么大费周章吧,那么此时我们就要寻求可用的第三方库了。

github上有很多实现,但是支持跨平台且方便好用、稳定可靠的我只找到了两个,一个就是QxtGlobalShortcut(Qt5版本是QxtGlobalShortcut5),用这个库的人相对也比较多,我今天也主要介绍这种方法,另一个就是QHotkey,该库用的人较少,但是功能也很不错,具有以下特性:

  • 在Windows,Mac和X11上均可使用
  • 易于使用,可QKeySequence用于轻松快捷输入
  • 支持几乎所有常用键(取决于操作系统和键盘布局)
  • 允许直接输入键/修饰键组合
  • 支持同一快捷方式的多个QHotkey实例(具有优化)
  • 线程安全-可以在所有线程上使用(请参阅线程安全部分)
  • 如果需要,允许使用本机键码和修饰符

QxtGlobalShortcut项目地址:https://github.com/ddqd/qxtglobalshortcut5

QHotkey项目地址:https://github.com/xtuer/QHotkey

b1d3f4c6dbcb16c885b46c84ff9c0fe2.png

QxtGlobalShortcut使用方法

1、要想使用QxtGlobalShortcut,需要先到上方的github地址中下载该库,然后解压后放入自己的工程路径下,例如我将其放在了工程中的3rd文件中:

278c30ece37f95036e6c990c1b5b256b.png

2、然后在项目.pro文件中加入下面这句话:

include(3rd/qxtglobalshortcut5/qxt.pri)

当然这里的3rd/qxtglobalshortcut5/qxt.pri是我的路径,大家设置成自己的具体路径即可。

3、然后在需要使用全局热键的文件中添加头文件:

#include “qxtglobalshortcut.h”

4、现在就可以愉快的设置全局热键了,最简单的注册全局热键的方法只需要两行代码即可:

QxtGlobalShortcut *m_pShortcutA = new QxtGlobalShortcut(QKeySequence("Ctrl+A"), this);connect(m_pShortcutA, SIGNAL(activated()), this, SLOT(ctrlA()));

当然这样用有时候也会有一些问题,比如当我要注册的热键已经被占用时,此时会注册失败,但我们又没有任何提示,所以通常我会采用如下方法注册全局热键:

m_pShortcutA = new QxtGlobalShortcut(this);if (m_pShortcutA->setShortcut(QKeySequence("Ctrl+A")))    connect(m_pShortcutA, SIGNAL(activated()), this, SLOT(ctrlA()));else    g_MainWin->myMessageBox(1, "ctrl+A 快捷键已占用", 1);

除了注册热键,QxtGlobalShortcut还提供了setEnabled(bool)方法,该方法可以设置某个全局热键

是否可用:

m_pShortcutA->setEnabled(false);

那么注册完全局热键后,如果我不想用了,或者程序退出时要怎么反注册呢?QxtGlobalShortcut虽然有反注册功能unsetShortcut(),但其是一个私有接口,不对外开发,但是查看源码发现,QxtGlobalShortcut析构时会自动执行发注册操作,所以我们不必再做处理:

QxtGlobalShortcut::~QxtGlobalShortcut(){    if (qxt_d().key != 0)        qxt_d().unsetShortcut();}

如果真的需要在程序运行中使某个全局热键无效的话,可以使用我们上面说的setEnabled()函数。

示例代码

#ifndef GLOBALSHORTCUT_H#define GLOBALSHORTCUT_H#include #include "qxtglobalshortcut.h"#include #include //全局热键class GlobalShortcut : public QWidget{    Q_OBJECTpublic:    explicit GlobalShortcut(QWidget *parent = 0);signals:public slots:    void setShortcut();         //设置全局热键    void setShortcutEnabled();  //设置全局热键是否有效    void ctrlA();               //按下Ctrl+A响应    void ctrlB();               //按下Ctrl+B响应private:    QPushButton * m_pSetShortcut_Button;    QLabel *m_pLabel;    QPushButton * m_psetEnabled_Button;    QxtGlobalShortcut *m_pShortcutA;    QxtGlobalShortcut *m_pShortcutB;};#endif // GLOBALSHORTCUT_H
#include "GlobalShortcut.h"#include "widget.h"#include GlobalShortcut::GlobalShortcut(QWidget *parent) : QWidget(parent){    this->resize(350, 200);    this->setAttribute(Qt::WA_DeleteOnClose);    this->setWindowTitle("全局热键");    m_pSetShortcut_Button = new QPushButton("注册全局热键 Ctrl+A、Ctrl+B", this);    m_psetEnabled_Button = new QPushButton("设置全局热键无效", this);    m_pLabel = new QLabel(this);    m_pLabel->setAlignment(Qt::AlignCenter);    QFont font;    font.setPointSize(18);    m_pLabel->setFont(font);    QVBoxLayout *pVLayout = new QVBoxLayout();    pVLayout->addWidget(m_pSetShortcut_Button);    pVLayout->addWidget(m_psetEnabled_Button);    pVLayout->addWidget(m_pLabel);    this->setLayout(pVLayout);    connect(m_pSetShortcut_Button, SIGNAL(clicked(bool)), this, SLOT(setShortcut()));    connect(m_psetEnabled_Button, SIGNAL(clicked(bool)), this, SLOT(setShortcutEnabled()));}//设置全局热键void GlobalShortcut::setShortcut(){    //方法1    //m_pShortcutA = new QxtGlobalShortcut(QKeySequence("Ctrl+A"), this);    //方法2    m_pShortcutA = new QxtGlobalShortcut(this);    if (m_pShortcutA->setShortcut(QKeySequence("Ctrl+A")))    {        connect(m_pShortcutA, SIGNAL(activated()), this, SLOT(ctrlA()));    }    else        g_MainWin->myMessageBox(1, "ctrl+A 快捷键已占用", 1);    m_pShortcutB = new QxtGlobalShortcut(this);    if (m_pShortcutB->setShortcut(QKeySequence("Ctrl+B")))    {        connect(m_pShortcutB, SIGNAL(activated()), this, SLOT(ctrlB()));        m_pLabel->setText("全局热键可使用");        QPalette palette;        palette.setColor(QPalette::WindowText, Qt::blue);        m_pLabel->setPalette(palette);    }    else        g_MainWin->myMessageBox(1, "ctrl+B 快捷键已占用", 1);}//取消全局热键void GlobalShortcut::setShortcutEnabled(){    bool bFlag = m_pShortcutA->isEnabled();    bFlag = !bFlag;    m_pShortcutA->setEnabled(bFlag);    m_pShortcutB->setEnabled(bFlag);    if (bFlag)    {        m_psetEnabled_Button->setText("设置全局热键无效");        m_pLabel->setText("全局热键可使用");        QPalette palette;        palette.setColor(QPalette::WindowText, Qt::blue);        m_pLabel->setPalette(palette);    }    else    {        m_psetEnabled_Button->setText("设置全局热键有效");        m_pLabel->setText("全局热键已禁用");        QPalette palette;        palette.setColor(QPalette::WindowText, Qt::red);        m_pLabel->setPalette(palette);    }}//按下Ctrl+A响应void GlobalShortcut::ctrlA(){    g_MainWin->myMessageBox(0, "你按下了 ctrl+A 快捷键", 1);}//按下Ctrl+B响应void GlobalShortcut::ctrlB(){    g_MainWin->myMessageBox(0, "你按下了 ctrl+B 快捷键", 1);}
efed0c124c482a7acedb786cbdd87605.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值