update server
This commit is contained in:
@@ -0,0 +1,167 @@
|
||||
#!/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()
|
||||
Reference in New Issue
Block a user