一個朋友有這方面的需求,于是用AI寫了一個小工具,順便分享給大家
https://wwzh.lanzout.com/idSTx31o9bkj
升級一版:新增自定義多次點擊時間間隔設置功能;顯著優化文件大小。下載鏈接:
https://wwzh.lanzout.com/iZ2Mg31ri6ri
![圖片[1]-[Windows] 利用AI技術打造超精準鼠標定時點擊器_精確到毫秒](http://www.oilmaxhydraulic.com.cn/wp-content/uploads/2025/07/d2b5ca33bd20250725230410.png)
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()
![圖片[2]-[Windows] 利用AI技術打造超精準鼠標定時點擊器_精確到毫秒](http://www.oilmaxhydraulic.com.cn/wp-content/uploads/2025/07/d2b5ca33bd20250725230438.png)
? 版權聲明
THE END