我的目标是在应用层获取到鼠标位置,并在特定时间点击记录到的位置。
总共有两种方法:
-
通过linux inpout event设计程序 ,通过这个实验,没有实现想要的效果。
-
xdotool是linux下,类似"按键精灵",在一些自动测试中经常用到。
ubuntux下的安装方式:
sudo apt-get install xdotool
在C/C++运行期间调用shell脚本有三种方法: system、popen、exec系列函数。system,exec都是通过fork()调用
execv要调用fork()函数调用子程序,在C/C++程序中有时会导致创建子进程失败,所以不使用。
为了获取指令运行结果,选择popen来调用子进程运行linux指令。
程序主要问题是通过指令返回值解析到鼠标的x,y坐标。xdotool getmouselocation获取到鼠标位置: x:1 y:2 window:......,我们只需解析到x: y:后面的数字即可。
获取鼠标位置:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <linux/input.h>
#include <fcntl.h>
#include <linux/uinput.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <QKeyEvent>
#include <QWidget>
struct mouse_pos{
int mpos_x;
int mpos_y;
};
struct mouse_pos mouse_dispos;
int Monitor::get_mouse_position(){
FILE *fp=NULL;
char *buff=NULL;
buff =(char*)malloc(26);
if(buff == NULL){
perror("malloc error:\n");
// return -1;
}
memset(buff,0,26);
fp=popen("xdotool getmouselocation","r");
if (fp ==NULL){
perror("popen error:\n");
free(buff);
// return -1;
}
fgets(buff,26,fp);
qDebug()<<buff<<" 77"<<endl;
QString mousposi=buff;
pclose(fp);
free(buff);
//将xdotool的结果进行 qt 正则匹配
QRegExp rx("x:(\\d+)\\sy:(\\d+)\\s");
rx.indexIn(mousposi,0);
ui->desPos_X->setText(rx.cap(1));
ui->desPos_Y->setText(rx.cap(2));
mouse_dispos.mpos_x=rx.cap(1).toInt();
mouse_dispos.mpos_y=rx.cap(2).toInt();
return 0;
}
模拟按键函数:
int Monitor::mouse_simulate_click()
{
string abx=to_string(mouse_dispos.mpos_x);
char* abs_x=const_cast<char*>(abx.c_str());
// char* abs_x=const_cast<char*>(to_string(mouse_dispos.mpos_x).c_str());
string aby=to_string(mouse_dispos.mpos_y);
char* abs_y=const_cast<char*>(aby.c_str());
// char *argv[]={"xdotool", "mousemove",abs_x,abs_y,"click","1",NULL };
qDebug()<<"click"<<abs_x<<abs_y<<endl;
// if(fork() ==0)
// {
// execv("/bin/xdotool",argv);
// }else{
// printf("This is the parent process\n");
// }
FILE *fp=NULL;
char buffer[5];
stringstream argv1;
argv1<<"xdotool "<<"mousemove "<<abs_x<<" "<<abs_y<<" click "<<"1";
fp=popen(const_cast<char*>(argv1.str().c_str()),"r");
fgets(buffer,sizeof(buffer),fp);
printf("%s",buffer);
pclose(fp);
ui->textEdit->setText("click fsbcer button");
return 0;
}
参考文献: