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六大开源框架对比
Oct 19 Python
分享python数据统计的一些小技巧
Jul 21 Python
使用Python中的tkinter模块作图的方法
Feb 07 Python
numpy.std() 计算矩阵标准差的方法
Jul 11 Python
Python 多个图同时在不同窗口显示的实现方法
Jul 07 Python
python3安装crypto出错及解决方法
Jul 30 Python
Python  Django 母版和继承解析
Aug 09 Python
对python中UDP,socket的使用详解
Aug 22 Python
为什么说Python可以实现所有的算法
Oct 04 Python
Python:type、object、class与内置类型实例
Dec 25 Python
python os模块在系统管理中的应用
Jun 22 Python
Python 如何在字符串中插入变量
Aug 01 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 Ajax中文乱码问题解决方法
2009/02/27 PHP
PHP高级OOP技术演示
2009/08/27 PHP
PHP中substr()与explode()函数用法分析
2014/11/24 PHP
php实现表单多按钮提交action的处理方法
2015/10/24 PHP
PHP运用foreach神奇的转换数组(实例讲解)
2018/02/01 PHP
document.getElementById方法在Firefox与IE中的区别
2010/05/18 Javascript
JavaScript的类型转换(字符转数字 数字转字符)
2010/08/30 Javascript
JavaScript格式化数字的函数代码
2010/11/30 Javascript
JS在TextArea光标位置插入文字并实现移动光标到文字末尾
2013/06/21 Javascript
js简单实现标签云效果实例
2015/08/06 Javascript
js数字舍入误差以及解决方法(必看篇)
2017/02/28 Javascript
Vue.js实现微信过渡动画左右切换效果
2017/06/13 Javascript
详解cordova打包成webapp的方法
2017/10/18 Javascript
React Native自定义控件底部抽屉菜单的示例
2018/02/08 Javascript
浅谈AngularJS中$http服务的简单用法
2018/05/15 Javascript
使用D3.js构建实时图形的示例代码
2018/08/28 Javascript
angularjs的单选框+ng-repeat的实现方法
2018/09/12 Javascript
利用Angular2的Observables实现交互控制的方法
2018/12/27 Javascript
修改layui的后台模板的左侧导航栏可以伸缩的方法
2019/09/10 Javascript
jquery实现图片无缝滚动 蒙版遮蔽效果
2020/01/11 jQuery
python实现两个文件合并功能
2018/04/01 Python
Python使用win32 COM实现Excel的写入与保存功能示例
2018/05/03 Python
详解Python中的正则表达式
2018/07/08 Python
在ubuntu16.04中将python3设置为默认的命令写法
2018/10/31 Python
Python格式化字符串f-string概览(小结)
2019/06/18 Python
python 读写excel文件操作示例【附源码下载】
2019/06/19 Python
对Python中class和instance以及self的用法详解
2019/06/26 Python
详解Django定时任务模块设计与实践
2019/07/24 Python
深入解读CSS3中transform变换模型的渲染
2016/05/27 HTML / CSS
html5 canvas 实现光线沿不规则路径运动
2020/04/20 HTML / CSS
美国大城市最热门旅游景点门票:CityPASS
2016/12/16 全球购物
函授毕业自我鉴定
2013/12/19 职场文书
幼儿园中班新学期寄语
2014/01/18 职场文书
商场开业庆典策划方案
2014/06/02 职场文书
2014年医德医风工作总结
2014/11/13 职场文书
《认识年月日》教学反思
2016/02/19 职场文书