#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 自动控制 GUI 界面脚本 - 通过模拟用户操作设置目标压力 升级功能: 1. 加入坐标校准功能,摆脱写死的硬编码坐标 2. 自动寻找并置顶 GUI 窗口 3. 加入 PyAutoGUI 故障保护 (防失控) 使用方法: 1. 首次使用建议进行校准: python auto_test.py --calibrate --targets 50 80 100 2. 后续固定窗口位置后直接运行: python auto_test.py --targets 50 80 100 python tool/auto_test.py --calibrate --targets 50 80 100 180 170 130 200 210 270 290 280 250 175 165 100 45 """ import argparse import time import platform import pyautogui try: import pygetwindow as gw except ImportError: gw = None # 配置 PyAutoGUI pyautogui.FAILSAFE = True # 将鼠标移动到屏幕四个角落可紧急停止脚本 pyautogui.PAUSE = 0.3 # 每个动作后默认停顿 0.3 秒,让 UI 有时间反应 # 平台相关的全选快捷键:macOS 用 command,Windows/Linux 用 ctrl _MODIFIER_KEY = 'command' if platform.system() == 'Darwin' else 'ctrl' class GUIController: def __init__(self): # 默认坐标 (如果不使用 calibrate 模式,将使用这些备用坐标) # 注意:这些默认值是错误的,请务必使用 --calibrate 参数校准 self.input_x, self.input_y = 200, 150 self.btn_x, self.btn_y = 320, 150 def activate_window(self, title_keyword="ReinLoop"): """尝试寻找并激活目标窗口(支持部分标题匹配)""" if gw is None: print("⚠️ 未安装 pygetwindow,请手动确保 GUI 窗口在前台。") print(" 安装命令: pip install pygetwindow") return print(f"正在寻找包含 '{title_keyword}' 的窗口...") try: windows = gw.getWindowsWithTitle(title_keyword) if windows: win = windows[0] if win.isMinimized: win.restore() win.activate() print(f"✅ 成功激活窗口: {win.title}") time.sleep(1) # 等待窗口彻底弹出 else: print(f"⚠️ 未找到包含 '{title_keyword}' 的窗口。") print(f" 当前所有窗口列表:") all_wins = gw.getAllWindows() for w in all_wins: if w.title.strip(): print(f" - {w.title}") print(" 请确保 ReinLoop GUI 已打开,或使用 --calibrate 后手动置顶窗口。") except Exception as e: print(f"⚠️ 窗口激活失败: {e},请手动将窗口切换到前台。") def calibrate(self): """交互式坐标校准,动态获取按钮位置""" print("\n" + "=" * 40) print("🔧 进入坐标校准模式 (请不要切走窗口)") print("=" * 40) print("\n👉 请在 5 秒内将鼠标光标移动到【目标压力输入框】中心...") for i in range(5, 0, -1): print(f"\r倒计时: {i} 秒", end='') time.sleep(1) self.input_x, self.input_y = pyautogui.position() print(f"\n✅ 输入框坐标已记录: ({self.input_x}, {self.input_y})") print("\n👉 请在 5 秒内将鼠标光标移动到【设置目标】按钮中心...") for i in range(5, 0, -1): print(f"\r倒计时: {i} 秒", end='') time.sleep(1) self.btn_x, self.btn_y = pyautogui.position() print(f"\n✅ 按钮坐标已记录: ({self.btn_x}, {self.btn_y})") print("=" * 40 + "\n") def set_target_pressure(self, target): """模拟用户操作设置目标压力""" print(f"▶ 正在设置目标压力: {target} kPa") try: # 点击输入框 pyautogui.click(x=self.input_x, y=self.input_y) # 全选并删除现有内容(macOS: command+a, Windows/Linux: ctrl+a) pyautogui.hotkey(_MODIFIER_KEY, 'a') pyautogui.press('backspace') # 输入新的目标压力值 pyautogui.typewrite(str(target)) # 点击"设置目标"按钮 pyautogui.click(x=self.btn_x, y=self.btn_y) print(f"✅ 成功设置目标压力: {target} kPa") return True except Exception as e: print(f"❌ 设置目标压力失败: {e}") return False def auto_control(targets, interval, do_calibrate): print("=" * 60) print("🤖 GUI 自动控制脚本启动") print("提示: 运行过程中将鼠标移动到屏幕四个角落即可紧急停止") print("=" * 60) controller = GUIController() controller.activate_window() if do_calibrate: controller.calibrate() else: print( f"ℹ️ 使用默认坐标 (输入框: {controller.input_x},{controller.input_y} | " f"按钮: {controller.btn_x},{controller.btn_y})") print("⚠️ 如果点击位置不准确,请使用 --calibrate 参数运行脚本。") print("\n3秒后开始自动控制序列...") time.sleep(3) for i, target in enumerate(targets): print(f"\n--- 步骤 {i + 1}/{len(targets)} ---") if not controller.set_target_pressure(target): print(f"❌ 步骤 {i + 1} 出现异常,提前终止自动控制") break if i < len(targets) - 1: print(f"等待 {interval} 秒...") for j in range(interval, 0, -1): print(f"\r剩余时间: {j} 秒 ", end='') time.sleep(1) print() print("\n🎉 自动控制序列全部完成!") def main(): parser = argparse.ArgumentParser(description='GUI 自动控制脚本') parser.add_argument('--targets', type=float, nargs='+', default=[50, 80, 100, 120], help='目标压力值列表,用空格隔开,单位 kPa') parser.add_argument('--interval', type=int, default=10, help='每个目标压力持续时间,单位秒') parser.add_argument('--calibrate', action='store_true', help='启动坐标校准模式,动态获取输入框和按钮的屏幕坐标') args = parser.parse_args() auto_control(args.targets, args.interval, args.calibrate) if __name__ == "__main__": main()