突发奇想,想要解决一些重复性的点击工作,比如抢票或者其他需要点击刷手速的地方,写了这么一个Exe文件
效果如下:
模拟鼠标
然后我们就来说细节部分,首先是我的界面设计,如下图所示:
我先讲一哈我的设置思路,首先人为的点击鼠标,获取到我们想要点击的鼠标位置,然后再将这个鼠标位置记录下来,通过WinUser.h这个C++的头文件,来实现模拟鼠标点击。
在实现这个功能的时候,我遇到了一个问题如何获取到点击的鼠标位置,我对QT进行了研究,决定通过重写mousePressEvent函数来实现,获取鼠标位置,因为到人点击鼠标的时候吗,就会触发这个mousepressevent这个函数,我给它加了限定条件,只有在获取鼠标的判定条件打开时,才会记录该鼠标位置,并显示到UI界面上面。
但是在写完代码以后我才发现,有一个比较严重的地方,就是鼠标事件只能读取到,QT界面里面的位置,因此我采取了一个大胆的方式,读取坐标位置的时候,将整个界面放大到整个屏幕,但是为了用户能够找到自己要点击的鼠标位置,我又把界面进行透明化,在选好位置以后,通过按键q,退出,即可。
然后剩下的就交给mouse_event来模拟人为鼠标点击。
最后就是代码部分!!!
h头文件的代码如下:
#ifndef CLICK_H
#define CLICK_H
#include
#include
#include
#include
#include "ui_click.h"
QT_BEGIN_NAMESPACE
namespace Ui { class click; }
QT_END_NAMESPACE
class click : public QMainWindow
{
Q_OBJECT
public:
click(QWidget *parent = nullptr);
~click();
POINT pos = {0,0} ; //保存鼠标点击点的x、y坐标。这里的坐标值是整个显示屏幕窗口的坐标 //与Qt程序窗口无关。与你操作系统的分辨率有关。
void hide_all();
void show_all();
public slots:
void mousePressEvent(QMouseEvent *event);
void keyPressEvent(QKeyEvent *event);
void doPressleftAct();//执行鼠标左键动作。
void doPressrightAct();//执行鼠标左键动作
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
void on_radioButton_clicked();
void on_radioButton_2_clicked();
protected:
void paintEvent(QPaintEvent *event) override;
private:
bool ok;
int click_num;//点击次数
float time; //控制间隔时间
bool mouse_type_pand=false;//控制鼠标点击类型
int notfixed=0;//控制是否采集坐标
Ui::click *ui;
};
#endif // CLICK_H
cpp文件是如下代码:
#include "click.h"
#include "ui_click.h"
#include "QDebug"
#include
#include
#include
#include
#include
#include
#pragma execution_character_set("utf-8")
click::click(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::click)
{
ui->setupUi(this);
ui->radioButton->setChecked(1);
QButtonGroup *block1=new QButtonGroup(this); //分组
block1->addButton(ui->radioButton,1); //一个值为0
block1->addButton(ui->radioButton_2,0); //一个值为1
ui->lineEdit_3->setPlaceholderText("Doublesize");
}
click::~click()
{
delete ui;
}
void click::doPressleftAct()//模拟按键单击,区分左右
{
int x=pos.x;
int y=pos.y;
SetCursorPos(x,y);//移动鼠标位置
//鼠标单击一下左键
// mouse_event (MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, x, y, 0, 0 );
// mouse_event (MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, x, y, 0, 0 );
// mouse_event (MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, x, y, 0, 0 );
mouse_event(MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_LEFTDOWN,x, y, 0, 0);
mouse_event(MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_LEFTUP,x, y, 0, 0);
// if(type_id==2)
// {//鼠标单击右键
// qDebug()<setWindowFlags(Qt::FramelessWindowHint);
QList widgets = this->findChildren();
this->setWindowOpacity(0.3);
this->showMaximized();
for (int i = 0; i < widgets.size(); i++)
{
// qDebug() << widgets[i]->objectName();
widgets[i]->setVisible(false);
}
}
void click::show_all()//展示所有
{
this->showNormal();
QList widgets = this->findChildren();//批量获得当前页面所有控件信息
for (int i = 0; i < widgets.size(); i++)
{
// qDebug() << widgets[i]->objectName();
widgets[i]->setVisible(true);
}
this->setWindowOpacity(1);
this->setWindowFlags(Qt::Window);
this->show();
notfixed=0;
}
void click::mousePressEvent(QMouseEvent *event)//重写检测鼠标按下功能,并画点表示
{
//未取定坐标值时,取坐标值。否则不做什么。
qDebug()<button ()==Qt::LeftButton){
GetCursorPos(&pos);
qDebug()<lineEdit->setText (QString::number (pos.x)+","+QString::number (pos.y));
repaint();
}
}
}
void click::keyPressEvent(QKeyEvent *event)
{
// 判断按下的键是不是 Qt::Key_q
if (event->key() == Qt::Key_Q) {
// 处理按下 Q 键的逻辑
// qDebug() << "You pressed Q key";
show_all();
}
// 调用父类的默认实现
QWidget::keyPressEvent(event);
}
void click::doPressrightAct()
{
int x=pos.x;
int y=pos.y;
SetCursorPos(x,y);//移动鼠标位置
if(mouse_type_pand)
{//鼠标单击右键
mouse_event(MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_RIGHTDOWN,x, y, 0, 0);
mouse_event(MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_RIGHTUP,x, y, 0, 0);
}
}
void click::on_pushButton_clicked()
{
// qDebug()<<"1";
notfixed=1;
// qDebug()<<"2";
hide_all();
}
void click::on_pushButton_2_clicked()
{
ui->plainTextEdit->clear();
time = ui->lineEdit_2->text().toFloat(); // num = 123, ok = true
click_num=ui->lineEdit_3->text().toInt(&ok);
// qDebug()<<"panding"<plainTextEdit->appendPlainText("第"+QString::number(i+1)+"次数");
}
}
else{
if(!mouse_type_pand)
doPressleftAct();
else
doPressrightAct();
}
}
void click::on_radioButton_clicked()
{
mouse_type_pand=false;
// qDebug()<
在这里,再解释一哈代码,使用的时候,需要先选择鼠标位置(用鼠标点击即可,会在屏幕下面留下痕迹,如果觉得位置不对,就再次点击,会改变记录的位置,并刷新为当前位置的),然后按q键(英文)退出即可,然后根据自己需要,进行左键或右键的选择,然后点击模拟点击按钮就会开始运行了。
由于这是兴致使然,突发奇想写的exe,所以肯定有很多不足的地方,供大家学习和交流,批评改进。如果觉得对您有帮助,请点赞,收藏,关注三连哟!(*^▽^*)
然后我的下一步计划,就是做一个简单的模拟位置和时间间隔,以及点击类型的存储,从而实现一个整套的,解放双手的模拟点击软件,说不定可以用到游戏的脚本上面哈哈。
************************************************************************************************************* 在这里主要是写其他模拟鼠标点击的组合方式,比如
使用QWidget::mousePressEvent()和QWidget::mouseReleaseEvent()函数来重写控件的鼠标事件处理函数,并在其中调用QApplication::sendEvent()或QApplication::postEvent()函数将事件转发给其他控件。例如:
// 在自定义的Label类中重写鼠标事件处理函数
void Label::mousePressEvent(QMouseEvent *event)
{
// 调用父类的函数
QLabel::mousePressEvent(event);
// 如果是鼠标左键按下
if (event->button() == Qt::LeftButton) {
// 创建一个新的鼠标事件对象
QMouseEvent *newEvent = new QMouseEvent(event->type(), event->localPos(), event->windowPos(), event->screenPos(),
event->button(), event->buttons(), event->modifiers(), event->source());
// 将事件转发给lineEdit控件
QApplication::sendEvent(ui->lineEdit, newEvent);
}
}
void Label::mouseReleaseEvent(QMouseEvent *event)
{
// 调用父类的函数
QLabel::mouseReleaseEvent(event);
// 如果是鼠标左键释放
if (event->button() == Qt::LeftButton) {
// 创建一个新的鼠标事件对象
QMouseEvent *newEvent = new QMouseEvent(event->type(), event->localPos(), event->windowPos(), event->screenPos(),
event->button(), event->buttons(), event->modifiers(), event->source());
// 将事件转发给lineEdit控件
QApplication::sendEvent(ui->lineEdit, newEvent);
}
}
然后使用QObject::installEventFilterO函数为目标控件安装一个事件过滤器,并在过滤器中处理鼠标事件,例如:
// 在主窗口类中为label控件安装事件过滤器
ui->label->installEventFilter(this);
// 在主窗口类中重写eventFilter()函数
bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{
// 如果被监视的对象是label控件
if (watched == ui->label) {
// 如果事件类型是鼠标按下
if (event->type() == QEvent::MouseButtonPress) {
// 转换为鼠标事件对象
QMouseEvent *mouseEvent = static_cast(event);
// 如果是鼠标左键按下
if (mouseEvent->button() == Qt::LeftButton) {
// 在lineEdit控件中显示鼠标位置
ui->lineEdit->setText(QString("x=%1 y=%2").arg(mouseEvent->x()).arg(mouseEvent->y()));
// 返回true表示已经处理了该事件,不再向下传递
return true;
}
}
}
// 否则调用父类的函数
return QMainWindow::eventFilter(watched, event);
}
还有使用QCursor类的setPosO函数来设置鼠标的位置,并使用QTest类的mouseclickO或mousePressO和mouseReleaseO函数来模拟鼠标的点击。例如:
// 模拟鼠标左键点击
QCursor::setPos(100,200); // 移动到(100,200)位置
QTest::mouseClick(QApplication::desktop(), Qt::LeftButton); // 点击
// 模拟鼠标右键点击
QCursor::setPos(300,400); // 移动到(300,400)位置
QTest::mouseClick(QApplication::desktop(), Qt::RightButton); // 点击
但是要注意,使用QCursor的话,要包含#include
您需要在工程文件(.pro文件)中加入testlib模块:
QT += testlib
--------------------------------------------------------------------------------------------------------------------------------
用python实现模拟鼠标点击等
首先,你需要安装一些第三方库,如pyHook、PyUserInput、pyperclip等。您可以使用pip命令来安装这些库,例如:
pip install pyHook
pip install PyUserInput
pip install pyperclip
然后,你需要导入这些库,并创建鼠标和键盘对象,例如:
from pykeyboard import PyKeyboard
from pymouse import PyMouse
import pyperclip
k = PyKeyboard() # 创建键盘对象
m = PyMouse() # 创建鼠标对象
接下来,你可以使用这些对象的方法来模拟人为的操作,例如:
m.click(100, 200, 1) # 模拟鼠标在(100, 200)位置左键点击
k.type_string("Hello world!") # 模拟键盘输入"Hello world!"
k.tap_key(k.enter_key) # 模拟键盘敲击回车键
m.drag(100, 200, 300, 400) # 模拟鼠标从(100, 200)位置拖动到(300, 400)位置
在这里推荐一个不错的代码仓库给大家,链接如下:
python-zhengty158/模拟鼠标键盘-自动登录.py at master · zhengty158/python-zhengty158 (github.com)
代码部分如下:
# -*- coding: utf-8 -*-
# 模拟操作鼠标键盘,自动登录网站账号,这里以船讯网为例
# 需安装第三方库:pyautogui, pyperclip
# python3可用!
import pyautogui as gui, webbrowser as bro, pyperclip
from time import sleep
# 打开登录页面
print('\n\n 船讯网\n\n')
ship_name = input('请输入要查找的船名(中英文均可)或IMO号,按回车键确认:\n\n>>> ')
print('\n\n现在开始自动登录和查询船舶资料\n\n 不要动键盘鼠标!')
sleep(3)
bro.open('http://www.shipxy.com/Home/Login/')
sleep(8)
# 定义复制粘贴函数,实现自动输入汉字
def paste(word):
pyperclip.copy(word)
gui.hotkey('ctrl', 'v')
gui.click(x = 579, y = 6)
# 点击账户输入框
gui.click(x = 584, y = 267)
username = 'username'
password = 'password'
# 通过操作键盘自动找准输入框,输入账号密码
sleep(1)
paste(username)
gui.typewrite(['tab'])
paste(password)
gui.typewrite(['enter'])
sleep(8)
# 自动查询用户输入的船名或IMO号
gui.click(x = 126, y = 203)
paste(ship_name)
gui.typewrite(['enter'])
input('')
以上就是我对于模拟鼠标的分享,希望能给大家带来帮助。