前言

初始项目结构如下:

1
2
3
4
5
demo.pro
widget.h
main.cpp
widget.cpp
widget.ui

添加全局热键及函数

修改 widget.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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <windows.h>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
Q_OBJECT

public:
Widget(QWidget *parent = nullptr);
~Widget();

protected:
void showEvent(QShowEvent *event) override;
void closeEvent(QCloseEvent *event) override;
bool nativeEvent(const QByteArray &eventType, void *message, long *result) override;

private:
// 定义热键配置结构体
struct HotkeyConfig {
int id;
UINT modifiers;
UINT key;
std::function<void()> handler;
};

// 热键列表
const QList<HotkeyConfig> m_hotkeys = {
{1, MOD_CONTROL | MOD_SHIFT, 'A', [this](){ TestFunc1(); }},
{2, MOD_CONTROL | MOD_ALT, 'B', [this](){ TestFunc2(); }},
{3, MOD_WIN, VK_F1, [this](){ TestFunc3(); }}
};

// 声明多个处理函数
void TestFunc1();
void TestFunc2();
void TestFunc3();

Ui::Widget *ui;
};
#endif // WIDGET_H

修改 widget.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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>

Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
}

Widget::~Widget()
{
delete ui;
}

// 注册所有热键
void Widget::showEvent(QShowEvent *event)
{
QWidget::showEvent(event);

HWND hwnd = reinterpret_cast<HWND>(winId());
for (const auto& hotkey : m_hotkeys) {
if (!RegisterHotKey(hwnd, hotkey.id, hotkey.modifiers, hotkey.key)) {
qDebug() << "[错误] 热键" << hotkey.id << "注册失败";
}
}
}

// 统一处理热键消息
bool Widget::nativeEvent(const QByteArray &eventType, void *message, long *result)
{
MSG* msg = reinterpret_cast<MSG*>(message);

if (msg->message == WM_HOTKEY) {
for (const auto& hotkey : m_hotkeys) {
if (msg->wParam == hotkey.id) {
hotkey.handler(); // 执行对应的处理函数
*result = 0;
return true;
}
}
}
return QWidget::nativeEvent(eventType, message, result);
}

// 注销所有热键
void Widget::closeEvent(QCloseEvent *event)
{
HWND hwnd = reinterpret_cast<HWND>(winId());
for (const auto& hotkey : m_hotkeys) {
UnregisterHotKey(hwnd, hotkey.id);
}
QWidget::closeEvent(event);
}

// 具体功能实现
void Widget::TestFunc1()
{
qDebug() << "热键1触发:Ctrl+Shift+A";
// 功能1的具体实现...
}

void Widget::TestFunc2()
{
qDebug() << "热键2触发:Ctrl+Alt+B";
// 功能2的具体实现...
}

void Widget::TestFunc3()
{
qDebug() << "热键3触发:Win+F1";
// 功能3的具体实现...
}

修改 .pro 文件(关键配置)

1
2
3
4
# 添加Windows API库链接(必须)
win32 {
LIBS += -luser32
}

检查 main.cpp(无需修改)

1
2
3
4
5
6
7
8
9
10
#include "widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}

关键实现原理

  1. 热键配置集中管理

    • 使用结构体 HotkeyConfig 存储以下信息:

      1
      2
      3
      4
      5
      6
      struct HotkeyConfig {
      int id; // 唯一标识符
      UINT modifiers; // 修饰键(Ctrl/Alt/Shift等)
      UINT key; // 主键(字母或功能键)
      std::function<void()> handler; // 处理函数
      };
    • 通过 m_hotkeys 列表统一管理所有热键配置

  2. 自动注册/注销机制

    • showEvent 中遍历注册所有热键
    • closeEvent 中遍历注销所有热键
    • 新增热键只需修改 m_hotkeys 列表
  3. 统一消息处理

    • nativeEvent 中通过循环匹配热键ID
    • 使用 std::function 直接绑定处理函数