首页 > 其他分享 >Qt实现全局快捷键

Qt实现全局快捷键

时间:2024-11-25 10:12:24浏览次数:10  
标签:cast Qt Ctrl 快捷键 reinterpret winId 全局 include 图标

实现思路

使用 Windows API 在 Qt 应用程序中注册全局快捷键,使得用户无论在何种情况下都能通过特定的键组合来控制某些功能(例如音乐播放控制)。通过响应消息机制与系统托盘图标结合,提供用户友好的交互界面。

实现步骤

1. 创建 Qt 应用程序

  • 使用 Qt Creator 创建一个新的 Qt Widgets 应用程序项目。

2. 引入必要的头文件

在主窗口的 .cpp 文件中引入以下头文件:

#include <QApplication>
#include <QSystemTrayIcon>
#include <QMenu>
#include <QAction>
#include <QWidget>
#include <QMessageBox>
#include <windows.h>
#include <QDebug>

3. 创建主窗口类

继承自 QWidget,在类中添加系统托盘图标、快捷键注册和事件处理的相关代码。

4. 初始化系统托盘图标

在构造函数中,创建并设置系统托盘图标及其上下文菜单,添加退出程序的选项:

QSystemTrayIcon trayIcon;
QMenu *menu = new QMenu();
QAction *exitAction = menu->addAction("Exit");
QObject::connect(exitAction, &QAction::triggered, qApp, &QApplication::quit);
trayIcon.setContextMenu(menu);
trayIcon.setVisible(true);

5. 注册全局快捷键

使用 Windows API 的 RegisterHotKey 函数来注册需要的全局快捷键。在构造函数中执行以下代码:

RegisterHotKey(reinterpret_cast<HWND>(this->winId()), 1, MOD_CONTROL, VK_LEFT);  // Ctrl + Left
RegisterHotKey(reinterpret_cast<HWND>(this->winId()), 2, MOD_CONTROL, VK_RIGHT); // Ctrl + Right
RegisterHotKey(reinterpret_cast<HWND>(this->winId()), 3, MOD_CONTROL, VK_SPACE); // Ctrl + Space

6. 处理系统托盘图标的点击事件

使用信号和槽机制连接托盘图标的点击事件,提供用户反馈或打开/关闭主窗口的功能。

7. 实现 nativeEvent 方法

重写 nativeEvent 方法以处理 Windows 消息,捕获 WM_HOTKEY 消息并根据 wParam 值调用相应的功能(如上一曲、下一曲、播放/暂停):

bool nativeEvent(const QByteArray &eventType, void *message, long *result) override {
    MSG* msg = reinterpret_cast<MSG*>(message);
    if (msg->message == WM_HOTKEY) {
        switch (msg->wParam) {
            case 1: // Ctrl + Left
                previousTrack();
                break;
            case 2: // Ctrl + Right
                nextTrack();
                break;
            case 3: // Ctrl + Space
                playPauseTrack();
                break;
        }
        return true; // 表示事件已处理
    }
    return QWidget::nativeEvent(eventType, message, result); // 传递给基类处理
}

8. 实现快捷键对应的功能

定义槽函数,例如 previousTrack()nextTrack()playPauseTrack(),在其中实现具体的操作,比如显示消息框或控制实际的音乐播放逻辑。

9. 清理资源

在应用程序退出时,确保注销全局热键(可在适当位置调用 UnregisterHotKey,如在析构函数或关闭事件处理函数中):

UnregisterHotKey(reinterpret_cast<HWND>(this->winId()), 1);
UnregisterHotKey(reinterpret_cast<HWND>(this->winId()), 2);
UnregisterHotKey(reinterpret_cast<HWND>(this->winId()), 3);

10. 运行和测试

编译并运行应用程序,确保热键功能工作正常,托盘图标能够响应点击事件。

 

完整案例代码:

#include <QApplication>
#include <QSystemTrayIcon>
#include <QMenu>
#include <QAction>
#include <QWidget>
#include <QMessageBox>
#include <windows.h>
#include <QDebug>

class MusicControlApp : public QWidget {
public:
    MusicControlApp() {
        // 创建系统托盘图标
        trayIcon.setIcon(QIcon(":/Image/QQ图标.png"));
        trayIcon.setVisible(true);

        // 创建上下文菜单
        QMenu *menu = new QMenu();
        QAction *exitAction = menu->addAction("Exit");
        QObject::connect(exitAction, &QAction::triggered, qApp, &QApplication::quit);
        trayIcon.setContextMenu(menu);

        // 注册全局快捷键
        RegisterHotKey(reinterpret_cast<HWND>(this->winId()), 1, MOD_CONTROL, VK_LEFT);  // Ctrl + Left
        RegisterHotKey(reinterpret_cast<HWND>(this->winId()), 2, MOD_CONTROL, VK_RIGHT); // Ctrl + Right
        RegisterHotKey(reinterpret_cast<HWND>(this->winId()), 3, MOD_CONTROL, VK_SPACE); // Ctrl + Space

        // 处理托盘图标的点击事件
        QObject::connect(&trayIcon, &QSystemTrayIcon::activated, [&](QSystemTrayIcon::ActivationReason reason) {
            if (reason == QSystemTrayIcon::Trigger) {
                QMessageBox::information(nullptr, "Tray Icon Clicked", "You clicked the tray icon.");
            }
        });

        // 显示窗口
        this->setWindowTitle("Music Control App");
        this->resize(200, 100);
        this->show();
    }

protected:
    bool nativeEvent(const QByteArray &eventType, void *message, long *result) override {
        MSG* msg = reinterpret_cast<MSG*>(message);
        if (msg->message == WM_HOTKEY) {
            switch (msg->wParam) {
                case 1: // Ctrl + Left
                    previousTrack();
                    break;
                case 2: // Ctrl + Right
                    nextTrack();
                    break;
                case 3: // Ctrl + Space
                    playPauseTrack();
                    break;
            }
            return true; // 表示我们已经处理了这个事件
        }
        return QWidget::nativeEvent(eventType, message, result); // 传递给基类处理
    }

private slots:
    void previousTrack() {
        QMessageBox::information(nullptr, "Previous Track", "Previous track action triggered.");
        // 这里添加上一曲的实际功能代码
    }

    void nextTrack() {
        QMessageBox::information(nullptr, "Next Track", "Next track action triggered.");
        // 这里添加下一曲的实际功能代码
    }

    void playPauseTrack() {
        QMessageBox::information(nullptr, "Play/Pause", "Play/Pause action triggered.");
        // 这里添加播放/暂停的实际功能代码
    }

private:
    QSystemTrayIcon trayIcon;
};

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    app.setQuitOnLastWindowClosed(false);
    MusicControlApp musicApp; // 创建音乐控制应用实例
    return app.exec();
}

 

标签:cast,Qt,Ctrl,快捷键,reinterpret,winId,全局,include,图标
From: https://www.cnblogs.com/wang1299/p/18567046

相关文章

  • 基于uniapp的全局监听websocket连接及自动拨打电话号码
    定义一个全局的socket类,放在util目录下//定义一个socket类classWebSocket{constructor(url){this.url=urlthis.time=null;}//建立连接connet(){let_this=this;uni.connectSocket({url:_this.u......
  • Qt关于窗口一直调用paintEvent的踩坑实录
    首先看以下代码:voidItemBlockWidget::paintEvent(QPaintEvent*ev){//先调用父类的paintEvent以执行默认绘制行为QWidget::paintEvent(ev);qDebug()<<"ItemBlockWidget重绘";QStyleOptionopt;opt.initFrom(this);QPainterp(this);s......
  • KTL 一个支持C++14写公式的K线工具 - 0.9.2版,通达信mdt全景数据复盘大盘,Qt自定义图表
    K,K线,Candle蜡烛图。T,技术分析,工具平台L,公式Language语言使用c++14,Lite小巧简易。项目仓库:https://github.com/bbqz007/KTL    国内仓库:https://gitee.com/bbqz007/KTL 当前0.9.2新添加功能基于QCharts跟通达信mdt数据文件。使用者能够使用QCharts自定义数据处理图表。......
  • 按键 芯片型号qt2160 linux驱动程序
    /*qt2160.c-AtmelAT42QT2160TouchSenseControllerThisprogramisfreesoftware;youcanredistributeitand/ormodifyitunderthetermsoftheGNUGeneralPublicLicenseaspublishedbytheFreeSoftwareFoundation;eitherversion2oftheLicense,o......
  • 【QT】绘图
    个人主页~绘图一、绘图1、基础内容2、绘制形状(1)线段(2)矩形(3)圆形(4)文本(5)画笔(6)画刷3、绘制图片(1)简单图片(2)旋转图片4、其他(1)移动画家位置(2)保存、加载画家的状态5、其他(1)QPixmap(2)QImage修改像素点(3)QPicture一、绘图1、基础内容绘图可以帮助我们实现应对多种场景......
  • VsCode 快捷键[转载]
    前言VSCode的快捷键继承了一些IDE风格,有VS的身影,也有Emacs的身影。。简言之,内置快捷键玩熟了,效率提高不是一点两点。VsCode快捷键有五种组合方式(科普)Ctrl+Shift+?:这种常规组合按钮Ctrl+VCtrl+V:同时依赖一个按键的组合Shift+Vc:先组合后单键的输入Ctrl......
  • 作为前端工程师,不了解MQTT,只知道HTTP,那就是不合格啦。
    作为前端开发工程师,了解MQTT(MessageQueuingTelemetryTransport)协议是很有必要的。MQTT是一种轻量级的消息传输协议,主要用于物联网(IoT)设备之间的通信。一、MQTT协议特点轻量级MQTT协议设计简洁,占用带宽小,对硬件资源要求低,非常适合在资源受限的设备上使用,如传感器、嵌......
  • 【多式联运】基于AFO算法、GA和PSO算法求解不确定多式联运路径优化问题,同时和MATLAB自
    ......
  • 我开发了许多智能家居设备,支持通过MQTT接入home Assitant ,我想用php开发一个网站,通过
    您好,您想开发一个PHP网站,通过OpenAI的API和FunctionCalling功能,实现智能家居的控制。这是一个非常有趣的项目,下面我将为您提供实现思路和步骤。1.整体架构思路用户界面(PHP网站):用户可以在网站上与AI进行聊天。OpenAIAPI交互:将用户的输入发送给OpenAI的API,使用Functio......
  • 3. 使用Docker部署MQTT平台mosquitto到云服务器
    3.使用Docker部署MQTT平台mosquitto到云服务器1.拉取MosquittoDocker镜像(这里选择拉取1.6.14版本,因为最新版本报错Addressnotavailable)dockerpulleclipse-mosquitto#或者拉取1.6.14版本dockerpulleclipse-mosquitto:1.6.142.创建mosquitto配置文件在运......