Linux下全局监测按键与鼠标位置信息-Qt封装

本文介绍如何在C++中使用X11库创建keyScan类,实现对键盘按键和鼠标位置的实时监听,并展示了关键代码和使用方法。读者将学习到如何在跨平台环境中注册和注销XRecordContext,以及处理不同事件的回调函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前置准备:pro文件添加如下两个链接库

LIBS += -lX11  -lXtst

没安装就执行安装命令

sudo apt-get install xorg-dev libxcb-util0-dev

我将其封装成了一个类,可以直接使用

头文件:

#ifndef KEYSCAN_H
#define KEYSCAN_H
#include <QThread>

class keyScan : public QThread
{
    Q_OBJECT

public:
    explicit keyScan(QObject *parent = nullptr);
    virtual ~keyScan();

signals:
    void sig_buttonPressed(unsigned char);
    void sig_buttonRelease(unsigned char);

    void sig_keyPressed(unsigned char);
    void sig_keyRelease(unsigned char);

    void sig_mousePoint(int x,int y);

protected:
        void run();

private:
    void registerd();
    void unregister();
};

#endif // KEYSCAN_H

cpp文件

#include "keyscan.h"
#include <X11/Xlibint.h>
#include <X11/Xlib.h>
#include <X11/extensions/record.h>

Display * m_display;
XRecordRange * range;
XRecordContext m_context;
XRecordClientSpec clients;

static void recordEventCallback(char *, XRecordInterceptData *);

keyScan::keyScan(QObject *parent)
    : QThread( parent )
{
    registerd();
}

keyScan::~keyScan()
{
    unregister();
}

void keyScan::registerd()
{
    Display * display =XOpenDisplay(nullptr);
    clients = XRecordAllClients;
    range = XRecordAllocRange();
    memset(range, 0, sizeof(XRecordRange));
    range->device_events.first = KeyPress;
    range->device_events.last  = MotionNotify;
    m_context = XRecordCreateContext( display, 0, &clients, 1,&range, 1 );

    XFree(range);
    XSync( display, False );
    m_display = XOpenDisplay(nullptr);
}

void keyScan::run()
{
    XRecordEnableContext( m_display, m_context,recordEventCallback,(XPointer)this);
}


void recordEventCallback(char * ptr, XRecordInterceptData * data )
{

    if ( data->category == XRecordFromServer )
    {
        data->client_swapped = false;
        xEvent * event = (xEvent *) data->data;
        switch (event->u.u.type) {
        case ButtonPress:
        {
            emit ((keyScan*)ptr)->sig_buttonPressed(event->u.u.detail);
        }
            break;
        case ButtonRelease: {
            emit ((keyScan*)ptr)->sig_buttonRelease(event->u.u.detail);
        }
            break;
        case KeyPress:
        {
            emit ((keyScan*)ptr)->sig_keyPressed(((unsigned char*)data->data)[1]);
        }
            break;
        case KeyRelease:
        {
            emit ((keyScan*)ptr)->sig_keyRelease(((unsigned char*)data->data)[1]);
        }
            break;
        default:
            break;
        }
        emit ((keyScan*)ptr)->sig_mousePoint(event->u.keyButtonPointer.rootX,event->u.keyButtonPointer.rootY);
    }
    XRecordFreeData( data );
}

void keyScan::unregister()
{
    Display * display = XOpenDisplay(nullptr);
    XRecordDisableContext( display, m_context );
    XSync( display, 0 );
    wait();
    XRecordFreeContext( display, m_context );
    XCloseDisplay(m_display );
}

使用方法:

 keyScan * btnCheck = new keyScan(this);
    connect(btnCheck,&keyScan::sig_keyPressed,this,[=](unsigned char c){

        qDebug()<<"key Pressed:" <<c;
    });

    connect(btnCheck,&keyScan::sig_keyRelease,this,[=](unsigned char c){

        qDebug()<<"key Release: " <<c;
    });

    connect(btnCheck,&keyScan::sig_buttonPressed,this,[=](unsigned char c){

        qDebug()<<"button Pressed:" <<c;
    });

    connect(btnCheck,&keyScan::sig_buttonRelease,this,[=](unsigned char c){

        qDebug()<<"button release" <<c;
    });

    connect(btnCheck,&keyScan::sig_mousePoint,this,[=](int x,int y){

        qDebug()<<"x:" <<x <<",y:"<<y;
    });
    btnCheck->start();

源代码 ,源码里key的release信号和pressed信号写倒了,自己改一下

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值