qt之在任意情况获取全局键盘按下事件

一、前言

一般来说,在使用键盘事件的时候,如果qt界面隐藏最小化或者不在顶层不是聚焦状态了,在按键盘就没有反应了,但是有的时候想在任何情况都要能通过键盘控制程序,所以本文的宗旨就是分享如何全局接收键盘事件。

二、环境

qt5.7  win8

三、正文

话不多说,先上程序,在pro目录下添加一个keypad文件夹,这个位置具体要放在哪里,还是根据个人习惯来定,反正这里加的代码后期也不需要整改。

文件夹内有capturer.h capturer.cpp keymonitor.h keymonitor.cpp

capturer.h

#ifndef CAPTURER_H
#define CAPTURER_H

#include <QObject>

/*捕获器*/


class KeyCapturer: public QObject
{
    Q_OBJECT

public:
    virtual ~KeyCapturer();
    static KeyCapturer*& instance()
    {
        static KeyCapturer *s = nullptr;
        if (s == nullptr)
        {
            s = new KeyCapturer();
        }
        return s;
    }

public:
    void setkeyValue(int key);

protected:
    KeyCapturer();

signals:
    void getKey(int);

private:
};
#endif // CAPTURER_H

 capturer.cpp

#include "keypad/capturer.h"

KeyCapturer::KeyCapturer()
{

}

KeyCapturer::~KeyCapturer()
{

}


void KeyCapturer::setkeyValue(int key)
{
    emit getKey(key);
}

keymonitor.h

#ifndef KEYMONITOR_H
#define KEYMONITOR_H

#include <Windows.h>
#include <DbgHelp.h>

int  startHook();

bool stopHook();

#endif // KEYMONITOR_H

keymonitor.cpp

#include "keypad/keymonitor.h"
#include "keypad/capturer.h"
#include <QtDebug>

LRESULT CALLBACK KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam);

HMODULE WINAPI ModuleFromAddress(PVOID pv);
static HHOOK hHook;

LRESULT KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    KBDLLHOOKSTRUCT *Key_Info = (KBDLLHOOKSTRUCT*)lParam;
    if (HC_ACTION == nCode)
    {
        if (WM_KEYDOWN == wParam || WM_SYSKEYDOWN == wParam)  //如果按键为按下状态
        {
            if (Key_Info->vkCode <= 107 && Key_Info->vkCode >= 65)
            {
                qDebug() << Key_Info->vkCode;
                if (KeyCapturer::instance())
                {
                    KeyCapturer::instance()->setkeyValue(Key_Info->vkCode);
                }
            }
        }
    }
    return CallNextHookEx(hHook, nCode, wParam, lParam);
}

HMODULE ModuleFromAddress(PVOID pv)
{
    MEMORY_BASIC_INFORMATION mbi;
    if (VirtualQuery(pv, &mbi, sizeof(mbi)) != 0) {
        return (HMODULE)mbi.AllocationBase;
    } else {
        return NULL;
    }
}

int startHook()
{
    hHook = SetWindowsHookExW(WH_KEYBOARD_LL, KeyboardHookProc, ModuleFromAddress((PVOID)KeyboardHookProc), 0);
    int error = GetLastError();
    return error;
}

bool stopHook()
{
    return UnhookWindowsHookEx(hHook);
}

 然后在mainwindow.h中加入

#include "keypad/keymonitor.h"
#include "keypad/capturer.h"

在mainwindow.cpp中加入

    connect( KeyCapturer::instance(), &KeyCapturer::getKey, [=](int key){
        qDebug()<<QString::number(key);
    });
    startHook();

 当然这个键盘监听事件也是可以关闭的

通过stopHook()这个函数即可。

2020年3月13日11:19:03更新

上面程序只是获取字母和小键盘的按键回调,如果想获取更多,如大键盘的数字和F1-F12等,将keymonitor.cpp内的107换成大一些即可。


方式二:使用qhotkey类

将开源代码放入到程序路径,并引入程序调用

调用方法,有两种方式传入检测的热键参数 

    QHotkey *hotkey=new QHotkey(QKeySequence("Ctrl+Shift+A"),true);
    //QHotkey *hotkey=new QHotkey(Qt::Key_L,Qt::ControlModifier,true);
    //连接热键被按下的信号与槽
    QObject::connect(hotkey,&QHotkey::activated,[=](){
        //热键被按下的处理代码段
        ui->btn_menu_1->click();//执行截图功能
    });

 程序下载

四、结语

qt监听全局键盘事件

  • 5
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大桶矿泉水

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值