前言

Linux下边做全局快捷键比较麻烦,Qt没有自带的库,Windows可以直接用Win API,但是这个理论到了Linux稍微有点问题,就是现在Linux的桌面环境分X11和Wayland,这两个桌面环境的接口不一样。如果实现其中一套另外一个环境就完全失效;如果两套都实现,Wayland因为还不是很成熟,用Wayland的原生接口来做又很麻烦。我经过一些努力后有一些阶段性的成果,就比如麒麟系统用的是KDE桌面环境,其实KDE桌面是有全局快捷键的接口的,用这个实现的话,就可以同时兼容X11/Wayland环境了。缺点就是只有KDE生效

至于KDE是怎么兼容X11/Wayland环境的,有待后续深入研究

示例

用到了KGlobalAccel库
.h头文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#ifndef GLOBALKEY_H
#define GLOBALKEY_H

#include <QObject>
#include <QAction>
#include <QKeyEvent>
#include <KF5/KGlobalAccel/KGlobalAccel>

class GlobalKey : public QObject
{
Q_OBJECT
public:
explicit GlobalKey(QObject *parent = nullptr);
void RegisterKey();
void UnregisterKey();

signals:
void sigKeyTriggered();

private:
QAction *m_pAction = nullptr;

};

#endif // GLOBALKEY_H

.cpp实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include "globalkey.h"
#include <QDebug>

GlobalKey::GlobalKey(QObject *parent) : QObject{parent}
{

}

void GlobalKey::RegisterKey()
{
if (m_pAction != nullptr)
{
qDebug()<<tr("shortcut key already create");
return;
}

m_pAction = new QAction(this);
m_pAction->setText(tr("GlobalKey"));
m_pAction->setObjectName(QStringLiteral("GlobalKeyAction"));
//when shortcut key had changed must restart kglobalaccel5
m_pAction->setProperty("compoentName", QStringLiteral("KylinNoteAction"));
qDebug()<<tr("check has:")<<KGlobalAccel::self()->hasShortcut(m_pAction);

KGlobalAccel::self()->setShortcut(m_pAction, QList<QKeySequence>{Qt::META + Qt::Key_Space});
KGlobalAccel::self()->setDefaultShortcut(m_pAction, QList<QKeySequence>{Qt::META + Qt::Key_Space});
qDebug()<<"key register successful.";

connect(m_pAction, &QAction::triggered, this, [this](){
qDebug()<<"注册的shutkey快捷键被触发";
emit sigKeyTriggered();
});
}

void GlobalKey::UnregisterKey()
{
if(m_pAction == nullptr)
{
return;
}

if (KGlobalAccel::self()->hasShortcut(m_pAction))
{
qDebug() << tr("ready unregister it");
KGlobalAccel::self()->removeAllShortcuts(m_pAction);
delete m_pAction;
m_pAction = nullptr;
}
else
{
qDebug()<<tr("can't find..the key")<<m_pAction->objectName();
}
}