前置准备: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信号写倒了,自己改一下