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

一、前言

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

二、环境

qt5.7  win8

三、正文

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

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

capturer.h

#ifndef CAPTURER_H
#define CAPTURER_H

#include 

/*捕获器*/


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 
#include 

int  startHook();

bool stopHook();

#endif // KEYMONITOR_H

keymonitor.cpp

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

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()<

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

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

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

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

四、结语

qt监听全局键盘事件

你可能感兴趣的:(#,qt数据处理/算法类,qt全局监听键盘,qt后台键盘,qt监听键盘)