概述:Qt 实现快捷键绑定和全局快捷键注册。

0x01、普通快捷键

使用 QShortcut

#include <QShortcut>
#include <QKeySequence>
 
// 创建快捷键
QShortcut *shortcut = new QShortcut(QKeySequence("Ctrl+S"), this);
connect(shortcut, &QShortcut::activated, this, &MainWindow::onSave);
 
// 使用标准键
QShortcut *copyShortcut = new QShortcut(QKeySequence::Copy, this);
connect(copyShortcut, &QShortcut::activated, this, &MainWindow::onCopy);
 
// 多键组合
QShortcut *shortcut = new QShortcut(QKeySequence("Ctrl+Shift+S"), this);

在 QAction 中设置

QAction *saveAction = new QAction("保存", this);
saveAction->setShortcut(QKeySequence::Save);  // Ctrl+S
connect(saveAction, &QAction::triggered, this, &MainWindow::onSave);
 
// 添加到菜单
QMenu *fileMenu = menuBar()->addMenu("文件");
fileMenu->addAction(saveAction);

使用快捷键编辑器

QAction *action = new QAction("自定义", this);
action->setShortcutContext(Qt::ApplicationShortcut);  // 应用级快捷键

0x02、全局快捷键(Windows)

方法一:使用 Windows API

#include <windows.h>
 
class GlobalHotkey : public QObject
{
    Q_OBJECT
public:
    GlobalHotkey(QObject *parent = nullptr) : QObject(parent) {}
    
    bool registerHotkey(HWND hwnd, int id, UINT modifiers, UINT vk)
    {
        return RegisterHotKey(hwnd, id, modifiers, vk);
    }
    
    bool unregisterHotkey(HWND hwnd, int id)
    {
        return UnregisterHotKey(hwnd, id);
    }
 
protected:
    bool nativeEvent(const QByteArray &eventType, void *message, long *result)
    {
        MSG *msg = static_cast<MSG*>(message);
        if (msg->message == WM_HOTKEY) {
            int hotkeyId = msg->wParam;
            emit hotkeyPressed(hotkeyId);
            return true;
        }
        return false;
    }
 
signals:
    void hotkeyPressed(int id);
};
 
// 使用
GlobalHotkey *hotkey = new GlobalHotkey(this);
connect(hotkey, &GlobalHotkey::hotkeyPressed, this, [](int id) {
    qDebug() << "Hotkey pressed:" << id;
});
 
// 注册快捷键 (Ctrl+Alt+A)
hotkey->registerHotkey((HWND)winId(), 1, MOD_CONTROL | MOD_ALT, 'A');

方法二:使用 QHotkey 库

#include <QHotkey>
 
// 安装:在 .pro 文件中添加
// QT += gui-private
 
QHotkey *hotkey = new QHotkey(QKeySequence("Ctrl+Alt+A"), true, this);
connect(hotkey, &QHotkey::activated, this, []() {
    qDebug() << "全局快捷键激活";
});

方法三:WinExtras(Qt 5)

#include <QtWinExtras>
 
// 需要添加 QT += winextras

0x03、快捷键修饰符

Qt 修饰符

修饰符说明
Qt::CTRLCtrl 键
Qt::SHIFTShift 键
Qt::ALTAlt 键
Qt::METAWindows/Meta 键

Windows API 修饰符

修饰符说明
MOD_ALTAlt 键
MOD_CONTROLCtrl 键
MOD_SHIFTShift 键
MOD_WINWindows 键
MOD_NOREPEAT按住不重复

0x04、完整示例

// globalhotkey.h
#ifndef GLOBALHOTKEY_H
#define GLOBALHOTKEY_H
 
#include <QObject>
#include <windows.h>
 
class GlobalHotkey : public QObject
{
    Q_OBJECT
public:
    explicit GlobalHotkey(QObject *parent = nullptr);
    ~GlobalHotkey();
    
    bool registerHotkey(int id, quint32 nativeModifiers, quint32 nativeKey);
    bool unregisterHotkey(int id);
    
protected:
    bool nativeEvent(const QByteArray &eventType, void *message, qintptr *result);
 
signals:
    void hotkeyActivated(int id);
    
private:
    QHash<int, bool> m_registeredHotkeys;
};
 
#endif
 
// globalhotkey.cpp
#include "globalhotkey.h"
#include <QDebug>
 
GlobalHotkey::GlobalHotkey(QObject *parent) : QObject(parent)
{
}
 
GlobalHotkey::~GlobalHotkey()
{
    foreach (int id, m_registeredHotkeys.keys()) {
        UnregisterHotKey(nullptr, id);
    }
}
 
bool GlobalHotkey::registerHotkey(int id, quint32 nativeModifiers, quint32 nativeKey)
{
    if (RegisterHotKey(nullptr, id, nativeModifiers, nativeKey)) {
        m_registeredHotkeys[id] = true;
        return true;
    }
    return false;
}
 
bool GlobalHotkey::unregisterHotkey(int id)
{
    if (UnregisterHotKey(nullptr, id)) {
        m_registeredHotkeys.remove(id);
        return true;
    }
    return false;
}
 
bool GlobalHotkey::nativeEvent(const QByteArray &eventType, void *message, qintptr *result)
{
    Q_UNUSED(eventType);
    Q_UNUSED(result);
    
    MSG *msg = static_cast<MSG*>(message);
    if (msg->message == WM_HOTKEY) {
        int hotkeyId = msg->wParam;
        emit hotkeyActivated(hotkeyId);
        return true;
    }
    return false;
}
 
// 使用示例
// mainwindow.cpp
#include "globalhotkey.h"
 
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    GlobalHotkey *hotkey = new GlobalHotkey(this);
    
    // 注册 Ctrl+Alt+T
    hotkey->registerHotkey(1, MOD_CONTROL | MOD_ALT, 'T');
    
    connect(hotkey, &GlobalHotkey::hotkeyActivated, this, [this](int id) {
        if (id == 1) {
            this->show();
            this->activateWindow();
        }
    });
}

0x05、开源项目


更新时间: 2026-03-27