当前位置: 首页 > web >正文

AI编写自动点击器 - 毫秒级精准鼠标连点器

使用很简单看图说话

源代码

import tkinter as tk
from tkinter import messagebox, ttk
import pyautogui
import time
import threading
from datetime import datetime, timedelta
from pynput import keyboard

class MouseAutoClicker:
def __init__(self, root):
self.root = root
self.root.title("鼠标自动点击器")
self.root.geometry("650x450")  # 增加窗口高度
self.root.resizable(False, False)

# 确保中文显示正常
self.style = ttk.Style()
self.style.configure("TLabel", font=("SimHei", 10))
self.style.configure("TButton", font=("SimHei", 10))
self.style.configure("TCheckbutton", font=("SimHei", 10))

# 设置变量
self.hour_var = tk.StringVar(value="15")
self.minute_var = tk.StringVar(value="40")
self.second_var = tk.StringVar(value="59")
self.millisecond_var = tk.StringVar(value="300")

self.x_pos = tk.StringVar(value="0")
self.y_pos = tk.StringVar(value="0")

self.click_type = tk.StringVar(value="左键")
self.click_count = tk.StringVar(value="1")
self.click_interval = tk.StringVar(value="0.1")  # 新增:点击间隔(秒)

self.is_running = False
self.click_thread = None
self.position_set = False

# 创建键盘监听器
self.key_listener = keyboard.Listener(on_press=self.on_key_press)
self.key_listener.start()

# 创建界面
self.create_widgets()

def create_widgets(self):
# 时间设置框架
time_frame = ttk.LabelFrame(self.root, text="设置点击时间")
time_frame.pack(fill="x", padx=15, pady=10)

ttk.Label(time_frame, text="小时:").grid(row=0, column=0, padx=5, pady=5)
self.hour_combo = ttk.Combobox(time_frame, textvariable=self.hour_var, width=5)
self.hour_combo['values'] = tuple(f"{i:02d}" for i in range(24))
self.hour_combo.grid(row=0, column=1, padx=5, pady=5)
self.hour_combo.bind('<FocusOut>', self.validate_time_input)

ttk.Label(time_frame, text="分钟:").grid(row=0, column=2, padx=5, pady=5)
self.minute_combo = ttk.Combobox(time_frame, textvariable=self.minute_var, width=5)
self.minute_combo['values'] = tuple(f"{i:02d}" for i in range(60))
self.minute_combo.grid(row=0, column=3, padx=5, pady=5)
self.minute_combo.bind('<FocusOut>', self.validate_time_input)

ttk.Label(time_frame, text="秒:").grid(row=0, column=4, padx=5, pady=5)
self.second_combo = ttk.Combobox(time_frame, textvariable=self.second_var, width=5)
self.second_combo['values'] = tuple(f"{i:02d}" for i in range(60))
self.second_combo.grid(row=0, column=5, padx=5, pady=5)
self.second_combo.bind('<FocusOut>', self.validate_time_input)

ttk.Label(time_frame, text="毫秒:").grid(row=0, column=6, padx=5, pady=5)
self.millisecond_combo = ttk.Combobox(time_frame, textvariable=self.millisecond_var, width=5)
self.millisecond_combo['values'] = tuple(f"{i:03d}" for i in range(0, 1000, 50))
self.millisecond_combo.grid(row=0, column=7, padx=5, pady=5)
self.millisecond_combo.bind('<FocusOut>', self.validate_time_input)

# 位置设置框架
position_frame = ttk.LabelFrame(self.root, text="设置点击位置")
position_frame.pack(fill="x", padx=15, pady=10)

ttk.Label(position_frame, text="X坐标:").grid(row=0, column=0, padx=5, pady=5)
x_entry = ttk.Entry(position_frame, textvariable=self.x_pos, width=10)
x_entry.grid(row=0, column=1, padx=5, pady=5)
x_entry.bind('<FocusOut>', self.validate_position_input)

ttk.Label(position_frame, text="Y坐标:").grid(row=0, column=2, padx=5, pady=5)
y_entry = ttk.Entry(position_frame, textvariable=self.y_pos, width=10)
y_entry.grid(row=0, column=3, padx=5, pady=5)
y_entry.bind('<FocusOut>', self.validate_position_input)

ttk.Label(position_frame, text="按F8记录当前鼠标位置").grid(row=0, column=4, padx=5, pady=5)

# 点击设置框架
click_frame = ttk.LabelFrame(self.root, text="点击设置")
click_frame.pack(fill="x", padx=15, pady=10)

ttk.Label(click_frame, text="点击类型:").grid(row=0, column=0, padx=5, pady=5)
click_type_combo = ttk.Combobox(click_frame, textvariable=self.click_type, width=8, state="readonly")
click_type_combo['values'] = ("左键", "右键", "中键")
click_type_combo.grid(row=0, column=1, padx=5, pady=5)

ttk.Label(click_frame, text="点击次数:").grid(row=0, column=2, padx=5, pady=5)
click_count_combo = ttk.Combobox(click_frame, textvariable=self.click_count, width=5)
click_count_combo['values'] = tuple(range(1, 11))
click_count_combo.grid(row=0, column=3, padx=5, pady=5)
click_count_combo.bind('<FocusOut>', self.validate_click_count)

# 新增:点击间隔设置
ttk.Label(click_frame, text="点击间隔(秒):").grid(row=1, column=0, padx=5, pady=5)
interval_entry = ttk.Entry(click_frame, textvariable=self.click_interval, width=10)
interval_entry.grid(row=1, column=1, padx=5, pady=5)
interval_entry.bind('<FocusOut>', self.validate_interval)

# 状态显示
self.status_var = tk.StringVar(value="就绪")
ttk.Label(self.root, textvariable=self.status_var).pack(pady=10)

# 按钮框架
button_frame = ttk.Frame(self.root)
button_frame.pack(pady=20)

self.start_button = ttk.Button(button_frame, text="开始", command=self.start_clicking, width=15)
self.start_button.pack(side="left", padx=10)

self.stop_button = ttk.Button(button_frame, text="停止", command=self.stop_clicking, width=15, state="disabled")
self.stop_button.pack(side="left", padx=10)

# 底部信息
ttk.Label(self.root, text="提示: 程序运行时请不要移动鼠标").pack(side="bottom", pady=10)

def on_key_press(self, key):
"""处理键盘按下事件"""
try:
if key == keyboard.Key.f8:
self.root.after(0, self.get_mouse_position)
except AttributeError:
pass

def get_mouse_position(self):
"""获取当前鼠标位置"""
x, y = pyautogui.position()
self.x_pos.set(str(x))
self.y_pos.set(str(y))
self.position_set = True
self.status_var.set(f"已记录鼠标位置: ({x}, {y})")

def validate_time_input(self, event):
"""验证并格式化时间输入"""
widget = event.widget

if widget == self.hour_combo:
value = self.hour_var.get()
try:
num = int(value)
if 0 <= num <= 23:
self.hour_var.set(f"{num:02d}")
else:
self.hour_var.set("00")
messagebox.showerror("输入错误", "小时数必须在0-23之间")
except ValueError:
self.hour_var.set("00")
messagebox.showerror("输入错误", "小时数必须是数字")

elif widget == self.minute_combo:
value = self.minute_var.get()
try:
num = int(value)
if 0 <= num <= 59:
self.minute_var.set(f"{num:02d}")
else:
self.minute_var.set("00")
messagebox.showerror("输入错误", "分钟数必须在0-59之间")
except ValueError:
self.minute_var.set("00")
messagebox.showerror("输入错误", "分钟数必须是数字")

elif widget == self.second_combo:
value = self.second_var.get()
try:
num = int(value)
if 0 <= num <= 59:
self.second_var.set(f"{num:02d}")
else:
self.second_var.set("00")
messagebox.showerror("输入错误", "秒数必须在0-59之间")
except ValueError:
self.second_var.set("00")
messagebox.showerror("输入错误", "秒数必须是数字")

elif widget == self.millisecond_combo:
value = self.millisecond_var.get()
try:
num = int(value)
if 0 <= num <= 999:
self.millisecond_var.set(f"{num:03d}")
else:
self.millisecond_var.set("000")
messagebox.showerror("输入错误", "毫秒数必须在0-999之间")
except ValueError:
self.millisecond_var.set("000")
messagebox.showerror("输入错误", "毫秒数必须是数字")

def validate_position_input(self, event):
"""验证并格式化坐标输入"""
widget = event.widget
var = self.x_pos if widget == event.widget.master.children['!entry'] else self.y_pos

value = var.get()
try:
num = int(value)
if num < 0:
var.set("0")
messagebox.showerror("输入错误", "坐标值不能为负数")
except ValueError:
var.set("0")
messagebox.showerror("输入错误", "坐标值必须是数字")

def validate_click_count(self, event):
"""验证点击次数输入"""
value = self.click_count.get()
try:
num = int(value)
if 1 <= num <= 10:
self.click_count.set(str(num))
else:
self.click_count.set("1")
messagebox.showerror("输入错误", "点击次数必须在1-10之间")
except ValueError:
self.click_count.set("1")
messagebox.showerror("输入错误", "点击次数必须是数字")

def validate_interval(self, event):
"""验证点击间隔输入"""
value = self.click_interval.get()
try:
num = float(value)
if num <= 0:
self.click_interval.set("0.1")
messagebox.showerror("输入错误", "点击间隔必须大于0")
elif num > 10:
self.click_interval.set("10.0")
messagebox.showerror("输入错误", "点击间隔不宜超过10秒")
except ValueError:
self.click_interval.set("0.1")
messagebox.showerror("输入错误", "点击间隔必须是数字")

def calculate_time_difference(self):
"""计算当前时间与目标时间的差值"""
try:
hour = int(self.hour_var.get())
minute = int(self.minute_var.get())
second = int(self.second_var.get())
millisecond = int(self.millisecond_var.get())

# 获取今天的日期
now = datetime.now()
target_time = now.replace(
hour=hour,
minute=minute,
second=second,
microsecond=millisecond * 1000
)

# 如果目标时间已经过去,则设置为明天
if target_time <= now:
target_time += timedelta(days=1)

# 计算时间差(秒)
time_diff = (target_time - now).total_seconds()
return time_diff
except Exception as e:
messagebox.showerror("错误", f"时间计算出错: {str(e)}")
return -1

def start_clicking(self):
"""开始点击任务"""
# 检查是否已设置位置
if not self.position_set:
messagebox.showwarning("警告", "请先设置点击位置")
return

# 计算时间差
time_diff = self.calculate_time_difference()
if time_diff < 0:
return

# 更新状态
self.is_running = True
self.start_button.config(state="disabled")
self.stop_button.config(state="normal")

# 计算倒计时显示
hours, remainder = divmod(int(time_diff), 3600)
minutes, seconds = divmod(remainder, 60)
milliseconds = int((time_diff - int(time_diff)) * 1000)
countdown_str = f"{hours:02d}:{minutes:02d}:{seconds:02d}.{milliseconds:03d}"
self.status_var.set(f"倒计时: {countdown_str}")

# 创建并启动线程
self.click_thread = threading.Thread(target=self.perform_clicking, args=(time_diff,))
self.click_thread.daemon = True
self.click_thread.start()

def perform_clicking(self, time_diff):
"""执行点击任务的线程函数"""
start_time = time.time()
target_time = start_time + time_diff

# 倒计时循环
while self.is_running and time.time() < target_time:
remaining = target_time - time.time()
if remaining < 0:
remaining = 0

hours, remainder = divmod(int(remaining), 3600)
minutes, seconds = divmod(remainder, 60)
milliseconds = int((remaining - int(remaining)) * 1000)
countdown_str = f"{hours:02d}:{minutes:02d}:{seconds:02d}.{milliseconds:03d}"

# 使用线程安全的方式更新UI
self.root.after(0, lambda cs=countdown_str: self.status_var.set(f"倒计时: {cs}"))
time.sleep(0.1)

# 执行点击
if self.is_running:
try:
x = int(self.x_pos.get())
y = int(self.y_pos.get())
count = int(self.click_count.get())
interval = float(self.click_interval.get())

# 移动到指定位置
pyautogui.moveTo(x, y)

# 根据选择的点击类型执行点击
click_func = {
"左键": pyautogui.click,
"右键": pyautogui.rightClick,
"中键": pyautogui.middleClick
}.get(self.click_type.get(), pyautogui.click)

for i in range(count):
if not self.is_running:
break
click_func()
if i < count - 1:  # 最后一次点击不需要等待
time.sleep(interval)
# 更新状态显示点击进度
self.root.after(0, lambda i=i+1: self.status_var.set(
f"正在执行点击 {i}/{count},间隔 {interval} 秒"))

self.root.after(0, lambda: self.status_var.set(
f"已完成所有点击: 在位置 ({x}, {y}) 执行 {count} 次{self.click_type.get()}点击,间隔 {interval} 秒"))
except Exception as e:
self.root.after(0, lambda: messagebox.showerror("错误", f"点击执行出错: {str(e)}"))

# 重置状态但不关闭程序
self.root.after(0, self.reset_after_complete)

def reset_after_complete(self):
"""任务完成后重置状态"""
self.is_running = False
self.start_button.config(state="normal")
self.stop_button.config(state="disabled")
self.status_var.set("就绪 - 点击次数和间隔已完成")

def stop_clicking(self):
"""停止点击任务"""
self.is_running = False
self.start_button.config(state="normal")
self.stop_button.config(state="disabled")
self.status_var.set("已停止")

def on_close(self):
"""关闭应用时的清理工作"""
self.is_running = False
self.key_listener.stop()
self.root.destroy()

if __name__ == "__main__":
root = tk.Tk()
app = MouseAutoClicker(root)
root.protocol("WM_DELETE_WINDOW", app.on_close)
root.mainloop()   

分享了「鼠标定时点击器 Rev1.exe」
链接:https://pan.quark.cn/s/abd00e979160

http://www.xdnf.cn/news/19987.html

相关文章:

  • kafka:【1】概念关系梳理
  • kvm 虚拟机如何安装 qemu-guest-agent
  • kali_linux
  • 【Linux】线程封装
  • 【FastDDS】Layer DDS之Domain ( 04-DomainParticipantFactory)
  • 采用基于模型的方法实现车辆SOA威胁分析自动化
  • wpf 自定义密码文本框,并且可以双向绑定
  • 吱吱企业通讯软件以安全为核心,构建高效沟通与协作一体化平台
  • 什么是Agent?小白如何学习使用Agent?一篇文档带你详细了解神秘的Agent
  • 容器tomcat镜像制作
  • 算法题2:动态规划
  • Python委托迭代完全指南:从基础到高级设计模式实践
  • Vision Pro图像处理工具全解析
  • Hadoop HDFS-SecondaryNameNode(2nn)详细介绍
  • PPI网络与TF-miRNA调控网络的实现方法(基于《列腺癌研究.pdf》)
  • 跟做springboot尚品甄选项目
  • 理解用户需求
  • 第6章:垃圾回收分析与调优
  • Java内存模型解析:并发编程的基石
  • DARPA OFFSET公开资料探究
  • GEO优化专家孟庆涛:优质内容是GEO优化的核心
  • 后端一次性返回十万条数据时,前端需要采用多种性能优化策略来避免页面卡顿
  • 日志打印--idf的esp32
  • Agent开发基础---提示词编写
  • 【数据分享】土地利用矢量shp数据分享-北京
  • AI Agent重构SOC:下一代智能安全运营平台的能力跃迁
  • 产线自动化效率上不去?打破设备和平台的“数据孤岛”是关键!
  • LeetCode 面试题 16.06.最小差
  • JavaScript原型与原型链:对象的家族传承系统
  • Springboot3+SpringSecurity6Oauth2+vue3前后端分离认证授权-资源服务