python之模拟鼠标键盘动作具体实现


Posted in Python onDecember 30, 2013

上个月就打算开发个还算好玩的项目,但是一直没时间。这篇是此项目用到的一部分,

处理好此部分基本还差通信等方面的了。首先模拟鼠标键盘按下释放的动作,本人利用X11

这个库,所以要了解X11编程;其次,本身用c或者c++就可以实现了,但是由于本人是py

粉,所以总想把代码搬进python,所以本人就要实现python模块,本篇用的ctypes,以后会

把python的c扩展模块附上来的。

1.X11编程

    首先简单的介绍一下X11吧,网上有介绍,本人就不重复了。我们知道X是以server与client

的方式提供服务的,我们想要使用其功能,我们就需要与server通信。使用

Display *XOpenDisplay(char *display_name)获得一个Display类型的句柄指针就可以了。

display_name可以是DISPLAY环境变量,用echo $DISPLAY输出是:0(这是本人linux mint输

出的)。如果display_name为NULL接口默认使用环境变量保存的值。X11编程常用的几个头

文件:

  #include <X11/Xlib.h>
  #include <X11/Xutil.h>
  #include <X11/Xos.h>

本人用到的是#include <X11/Xlib.h>和 #include <X11/extensions/XTest.h>.

XTest.h有我们模拟鼠标和键盘需要的接口XTestFakeButtonEvent、 XTestFakeMotionEvent和

XTestFakeKeyEvent。想了解更多信息只需要在终端上man加函数名即可获得。

比如XTestFakeMotionEvent接口:

int XTestFakeMotionEvent(display, screen_number, x, y,delay);
Display *display;  //此值就是从XOpenDisplay获得
int screen_number; //让其为-1即可表示当前的屏幕
int x, y;          //屏幕位置
unsigned long delay; //延迟毫秒,让其为CurrentTime表示不延迟

最后我们要关闭Display句柄:XCloseDisplay(Display *display)。

接口实现如下:

#include <stdio.h>
#include <X11/extensions/XTest.h>
#include <X11/Xlib.h>
Display *dspopen(){       Display *dsp = XOpenDisplay(NULL);
    if(!dsp) {
        printf("open display failed\n");
        return NULL;
    }
    return dsp;
}
int presskey(Display *dsp,int s){  //键盘按
    if(dsp==NULL)
        return -1;
//    KeySym keysym=XStringToKeysym(s);
    KeyCode key=XKeysymToKeycode(dsp,s);
    if(key==NoSymbol)
        return -1;
    XTestFakeKeyEvent(dsp,key,1,CurrentTime);
    XFlush(dsp);
    return 0;
}
int move(Display *dsp,int x,int y) //鼠标移动
{
    if(0==XTestFakeMotionEvent(dsp,-1,x,y,CurrentTime))
    {
        printf("Cannot move!\n");
        return -1;
    }
    return 0;
}
int buttonpress(Display *dsp,int type) //鼠标按,type=1表示左键,3是右键,2是中键
{
    if(0==XTestFakeButtonEvent(dsp,type,1,CurrentTime))
    {
        printf("press failed\n");
        return -1;
    }
    return 0;
}
int buttonrelease(Display *dsp,int type) //鼠标释放
{
    if(0==XTestFakeButtonEvent(dsp,type,0,CurrentTime))
    {
        printf("release failed\n");
        return -1;
    }
    return 0;
}
int releasekey(Display *dsp,int s){ //键盘release
    if(dsp==NULL)
        return -1;
//    KeySym keysym=XStringToKeysym(s);
    KeyCode key=XKeysymToKeycode(dsp,s);
    if(key==NoSymbol)
        return -1;
    XTestFakeKeyEvent(dsp,key,0,CurrentTime);
    XFlush(dsp);
    return 0;
}
void dspclose( Display *dsp ){
    if(dsp!=NULL){
        XCloseDisplay(dsp);
    }
}
//int main(){     //测试用的会在程序结束后,在光标前输出c
//    Display *dsp=dspopen();
//    presskey(dsp,'c');
//    releasekey(dsp,'c');
//    dspclose(dsp);
//    return 0;
//}

上面注释掉的main函数可以作为测试用的,好了,我们把上面的代码保存为display.c

编译成一个共享库,需要X11和Xtst库。

gcc -fPIC -shared -o libdisplay.so display.c -lX11 -lXtst

编译后会生成libdisplay.so 。现在我们ctypes模块使用这个动态共享库。

     2.ctypes简单介绍和使用

    我们知道python中的类型与c中类型是不一样的,应该说没有一样的,就拿int想来说,

python也是把它看作PyObject类型来处理的。那么我们需要使用ctype提供的接口做类型的

转换。见:http://docs.python.org/2/library/ctypes.html#fundamental-data-types

此链接有张图详细的展现类型转换对应的接口。下面演示具体的操作吧。

我们通过CDLL()接口载入库:

lc=CDLL("./libdisplay.so")

然后就可以使用库中提供的接口了,但是上面dspopen()接口的返回值是Display类型的指针,

所以我们需要用c_void_p()转换一下:

d=c_void_p(lc.dspopen())

之后就可以用d做处理了,代码如下:

from ctypes import *
import time
class MOUSE:
    LEFT=1
    MiDDLE=2
    RIGHT=3
lc=CDLL("./libdisplay.so")
d=c_void_p(lc.dspopen())
time.sleep(5);
lc.buttonpress(d,c_int(MOUSE.RIGHT))
lc.buttonrelease(d,c_int(MOUSE.RIGHT))
lc.dspclose(d)

上面的代码会在5秒后在鼠标指针处打开右键菜单。

利用ctypes使用c编写的库就讲这么多吧。以后会把c代码的部分写成python的c扩展再分享吧。

利用上面的模拟键盘和鼠标的接口可以做一些有意思的事情....

Python 相关文章推荐
Python内置函数bin() oct()等实现进制转换
Dec 30 Python
Python(Tornado)模拟登录小米抢手机
Nov 12 Python
python调用java的Webservice示例
Mar 10 Python
Python统计日志中每个IP出现次数的方法
Jul 06 Python
python语言使用技巧分享
May 31 Python
Python学习之Django的管理界面代码示例
Feb 10 Python
python中dir()与__dict__属性的区别浅析
Dec 10 Python
Python实现的旋转数组功能算法示例
Feb 23 Python
python实现栅栏加解密 支持密钥加密
Mar 20 Python
深入浅析Python 命令行模块 Click
Mar 11 Python
python 用Matplotlib作图中有多个Y轴
Nov 28 Python
python 学习GCN图卷积神经网络
May 11 Python
python多线程http下载实现示例
Dec 30 #Python
python正则匹配查询港澳通行证办理进度示例分享
Dec 27 #Python
python模拟登录百度代码分享(获取百度贴吧等级)
Dec 27 #Python
python读文件逐行处理的示例代码分享
Dec 27 #Python
python调用cmd复制文件代码分享
Dec 27 #Python
win7安装python生成随机数代码分享
Dec 27 #Python
python正则匹配抓取豆瓣电影链接和评论代码分享
Dec 27 #Python
You might like
php eval函数用法 PHP中eval()函数小技巧
2012/10/31 PHP
经常用到的JavasScript事件的翻译
2007/04/09 Javascript
关于juqery radio写法的兼容性问题(新老版本jquery)
2010/06/14 Javascript
JavaScript图片放大技术(放大镜)实现代码分享
2013/11/14 Javascript
jQuery动画效果animate和scrollTop结合使用实例
2014/04/02 Javascript
javascript实现页面内关键词高亮显示代码
2014/04/03 Javascript
理解javascript回调函数
2014/12/28 Javascript
jQuery同步提交示例代码
2015/12/12 Javascript
浅析Bootstrap验证控件的使用
2016/06/23 Javascript
jQuery中show与hide方法用法示例
2016/09/16 Javascript
BootStrap入门教程(三)之响应式原理
2016/09/19 Javascript
bootstrap IE8 兼容性处理
2017/03/22 Javascript
xmlplus组件设计系列之按钮(2)
2017/04/26 Javascript
解决Vue+Element ui开发中碰到的IE问题
2018/09/03 Javascript
vue中的过滤器实例代码详解
2019/06/06 Javascript
微信小程序实现侧边栏分类
2019/10/21 Javascript
webpack+vue-cil 中proxyTable配置接口地址代理操作
2020/07/18 Javascript
python2.7无法使用pip的解决方法(安装easy_install)
2018/04/03 Python
python实现简单淘宝秒杀功能
2018/05/03 Python
在python中实现求输出1-3+5-7+9-......101的和
2020/04/02 Python
django正续或者倒序查库实例
2020/05/19 Python
python help函数实例用法
2020/12/06 Python
经济学人订阅:The Economist
2018/07/19 全球购物
波兰化妆品和护肤品购物网站:eKobieca
2019/08/30 全球购物
自荐信怎么写好
2013/11/11 职场文书
机械绘图员岗位职责
2013/11/19 职场文书
升旗仪式演讲稿
2014/05/08 职场文书
会计毕业生自荐书
2014/06/12 职场文书
中职三好学生事迹材料
2014/08/24 职场文书
单位作风建设剖析材料
2014/10/11 职场文书
先进单位申报材料
2014/12/25 职场文书
2015年度党员个人总结
2015/02/14 职场文书
毕业生求职自荐信(2016最新版)
2016/01/28 职场文书
《童年的发现》教学反思
2016/02/18 职场文书
大学生,三分钟即兴演讲稿
2019/07/22 职场文书
Meta增速拉垮,元宇宙难当重任
2022/04/29 数码科技