首页 > 编程知识 正文

python检测键盘按键事件,用户点击鼠标后所发生的事件

时间:2023-05-04 10:04:35 阅读:156487 作者:4543

在此期间,需要完成确定工作中是否在一定时间内手动操作的功能,基本思路是在后台监听键盘和鼠标的输入事件。 那么,如何捕捉鼠标和键盘的事件呢? 介绍我们的实现原理和方法。

捕获设备输入事件的原理

打开/dev/input目录,然后运行ls命令,您将看到类似于以下内容的文件列表:

$ ls -l

总0

crw-r----.1根13,64 Jan 292018 event 0

crw-r----.1根13,65 Jan 292018 event 1

crw-r----.1根13,66 Jan 292018 event 2

crw-r----.1根13,67 Jan 292018 event 3

crw-r----.1根13,68 Jan 292018 event 4

crw-r----.1根13,63 Jan 292018 mice

crw-r----.1根13,32 Jan 292018 mouse 0

crw-r----.1根13,33 Jan 292018 mouse 1

crw-r----.1根13,34 Jan 292018 mouse 2

熟悉Linux的朋友一定知道这里列出的文件是设备文件。 在Linux环境下,/dev/input目录下的事件文件(event* )都是在驱动中调用input_register_device ) structinput_dev*dev生成的每个event都会提升指定的事件,如触摸、Mouse和按键。 读取这些事件文件时,会获取与该事件文件对应的设备的输入信息。

事件数据结构

linux/input.h文件定义了event事件的输入数据的结构。 该结构体的定义如下。

struct input_event {

struct timeval time;

__u16 type;

__u16代码;

__s32 value;

(;

time是事件发生的时间,具体定义如下:

结构时间

{

__time_t tv_sec; /* Seconds. */

__suseconds_t tv_usec; /* Microseconds. */

(;

type,指事件类型。 典型的事件类型包括:

EV_KEY、按键事件、键盘按键、鼠标左键、右键等

EV_REL,相对坐标,主要用于鼠标移动事件;

EV_ABS,绝对坐标,主要用于触摸屏的移动事件。

代码事件代码。 如果事件类型为EV_KEY,则此代码是设备键盘代码,在input.h文件中定义为以KEY_开头。

value事件的值。 如果事件类型代码为EV_KEY,则按键操作值为1,释放操作值为0,如果事件类型代码为EV_REL,则value表示正值,负值表示不同方向的值。

如何判断该事件文件适用于哪个设备

/proc/bus/input/device文件包含与事件对应的相关设备信息,如下所示:

$cat devices

I : bus=0019 vendor=0000 product=0001 version=0000

N: Name='Power Button '

p : phys=lnxpwrbn/button/input 0

s : sysfs=/devices/lnx systm :00/lnxpwrbn :00/input/input 0

U: Uniq=

H: Handlers=kbd event0

B: EV=3

b:key=100000000000

I : bus=0017 vendor=0001 product=0001 version=0100

n : name=' macintoshmousebuttonemulation '

P: Phys=

s : sysfs=/devices/virtual/input/input 1

U: Uniq=

H: Handlers=mouse0 event1

B: EV=7

B: KEY=70000 0 0 0 0

B: REL=3

I : bus=0011 vendor=0001 product=0001 version=ab41

n : name=' attranslatedset2keyboard '

P: Phys=is

a0060/serio0/input0

S: Sysfs=/devices/platform/i8042/serio0/input/input2

U: Uniq=

H: Handlers=kbd event2

B: EV=120013

B: KEY=402000000 3803078f800d001 feffffdfffefffff fffffffffffffffe

B: MSC=10

B: LED=7

I: Bus=0011 Vendor=0002 Product=0005 Version=0000

N: Name="ImPS/2 Generic Wheel Mouse"

P: Phys=isa0060/serio1/input0

S: Sysfs=/devices/platform/i8042/serio1/input/input3

U: Uniq=

H: Handlers=mouse1 event3

B: EV=7

B: KEY=70000 0 0 0 0

B: REL=103

在上面的H:中可以看到对应的eventxx。

捕捉键盘事件的实现方法

通过上节列出的文件,我们可以获得键盘对应的事件文件。通常键盘对应的事件文件为event2。监听这个文件,我们就能捕获到键盘的事件。

以下代码是我实现的监听键盘事件的函数代码,20秒内没有键盘事件,程序退出:

#include

#include

#include

#include

#include

#include

void listen_device(const char *dev, int timeout)

{

int retval;

fd_set readfds;

struct timeval tv;

int fd = open(dev, O_RDONLY);

struct input_event event;

if (fd < 0)

{

perror(dev);

return;

}

while (1)

{

FD_ZERO(&readfds);

FD_SET(fd, &readfds);

tv.tv_sec = timeout;

tv.tv_usec = 0;

if((retval = select(fd+1, &readfds, NULL, NULL, &tv)) == 1)

{

if (read(fd, &event, sizeof(event)) == sizeof(event))

{

if (event.type == EV_KEY)

{

if (event.value == 0 || event.value == 1)

{

printf("key %d %sn", event.code, event.value ? "Pressed" : "Released");

}

}

else

{

printf("type=%x %d %dn", event.type, event.code, event.value);

}

}

}

else

{

break;

}

}

close(fd);

}

void listen_keyboard(int timeout)

{

listen_device("/dev/input/event2", timeout);

}

int main(int argc, char **argv)

{

listen_keyboard(20);

printf("keyboard timeoutn");

return 0;

}

捕捉鼠标事件的实现方法

我们也可以通过上面的方面获取鼠标的event文件,从而实现鼠标事件的捕获。但事实上鼠标有更方便的捕获方法,就是同目录下的mice文件,通过该文件可以获取解析后的鼠标事件。

具体方法如下:

(1)打开"/dev/input/mice"文件。

(2)读3个字节。三个字节的值分别是“Button类型”,“X的相对位移”,“Y的相对位移”。这里先用Button, xRel, yRel表示。

(3)取Button的低3位(Button & 0x07)。0x00 = LeftButtonUp, 0x01 = LeftButtonDown, 0x02 = RightButtonDown.

以下代码是我实现的监鼠标事件的函数代码:

#include

#include

#include

#include

#include

#include

void listen_mice(const char *dev, int timeout)

{

char buf[256];

int n_len;

int retval;

fd_set readfds;

struct timeval tv;

int fd = open(dev, O_RDONLY);

if (fd < 0)

{

perror(dev);

return;

}

while (1)

{

FD_ZERO(&readfds);

FD_SET(fd, &readfds);

tv.tv_sec = timeout;

tv.tv_usec = 0;

if((retval = select(fd+1, &readfds, NULL, NULL, &tv)) == 1)

{

if ((n_len = read(fd, buf, sizeof(buf))) > 0)

{

if (n_len == 3)

{

printf("Button: %d, xRef=%d, yRef=%dn", buf[0]&0x07, buf[1], buf[2]);

}

}

}

else

{

break;

}

}

close(fd);

}

void listen_mouse(int timeout)

{

listen_mice("/dev/input/mice", timeout);

}

int main(int argc, char **argv)

{

listen_mouse (20);

printf("mouse timeoutn");

return 0;

}

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。