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使用正则表达式检测密码强度源码分享
Jun 11 Python
win7 下搭建sublime的python开发环境的配置方法
Jun 18 Python
Python中类的继承代码实例
Oct 28 Python
详细解读tornado协程(coroutine)原理
Jan 15 Python
对pandas中apply函数的用法详解
Apr 10 Python
python实现可视化动态CPU性能监控
Jun 21 Python
Python使用random模块生成随机数操作实例详解
Sep 17 Python
解决pycharm debug时界面下方不出现step等按钮及变量值的问题
Jun 09 Python
在Ubuntu中安装并配置Pycharm教程的实现方法
Jan 06 Python
如何用python插入独创性声明
Mar 31 Python
PySwarms(Python粒子群优化工具包)的使用:GlobalBestPSO例子解析
Apr 05 Python
PYTHON基于Pyecharts绘制常见的直角坐标系图表
Apr 28 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
模板引擎smarty工作原理以及使用示例
2014/05/25 PHP
php使用递归函数实现数字累加的方法
2015/03/16 PHP
php输出xml属性的方法
2015/03/19 PHP
PHP滚动日志的代码实现
2015/06/10 PHP
详解CSS样式中的 !important * _ 符号
2021/03/09 HTML / CSS
javascript 防止刷新,后退,关闭
2010/08/07 Javascript
js中页面的重新加载(当前页面/上级页面)及frame或iframe元素引用介绍
2013/01/24 Javascript
javascript表单验证使用示例(javascript验证邮箱)
2014/01/07 Javascript
js实现从中间开始往上下展开网页窗口的方法
2015/03/02 Javascript
JavaScript实现页面5秒后自动跳转的方法
2015/04/16 Javascript
JS模仿编辑器实时改变文本框宽度和高度大小的方法
2015/08/17 Javascript
js实现简洁的TAB滑动门效果代码
2015/09/06 Javascript
angularjs学习笔记之简单介绍
2015/09/26 Javascript
jQuery实现可兼容IE6的滚动监听功能
2017/09/20 jQuery
理解Koa2中的async&amp;await的用法
2018/02/05 Javascript
详解使用mpvue开发github小程序总结
2018/07/25 Javascript
微信小程序实现横向滚动导航栏效果
2019/12/12 Javascript
javascript canvas封装动态时钟
2020/09/30 Javascript
python中numpy.zeros(np.zeros)的使用方法
2017/11/07 Python
MAC中PyCharm设置python3解释器
2017/12/15 Python
python3下实现搜狗AI API的代码示例
2018/04/10 Python
python numpy中cumsum的用法详解
2019/10/17 Python
python 循环数据赋值实例
2019/12/02 Python
纯CSS3实现圆圈动态发光特效动画的示例代码
2021/03/08 HTML / CSS
借助HTML5 Canvas来绘制三角形和矩形等多边形的方法
2016/03/14 HTML / CSS
美国最大的在线寄售和旧货店:Swap.com
2018/08/27 全球购物
园林技术个人的自我评价
2014/01/08 职场文书
网上快餐厅创业计划书
2014/02/01 职场文书
六个一活动实施方案
2014/03/21 职场文书
学生请假条格式
2014/04/11 职场文书
绿色小区申报材料
2014/08/22 职场文书
2014党员学习兰辉先进事迹思想汇报
2014/09/17 职场文书
爱牙日宣传活动总结
2015/02/05 职场文书
飞越疯人院观后感
2015/06/09 职场文书
初中同学会致辞
2015/08/01 职场文书
springmvc直接不经过controller访问WEB-INF中的页面问题
2022/02/24 Java/Android