1. 项目背景与核心需求
这个项目的核心目标是开发一个能够实时显示鼠标位置的桌面工具,并将其打包成独立的exe可执行文件。这类工具在自动化测试、游戏辅助开发(如openclaw这类自动化工具)以及UI自动化操作中有着广泛的应用场景。
为什么我们需要这样一个工具?在自动化操作和脚本开发过程中,精确获取鼠标坐标是基础中的基础。比如:
- 开发游戏自动化脚本时,需要知道特定按钮的屏幕坐标
- 编写UI测试用例时,需要验证鼠标是否准确点击了目标元素
- 制作教学演示时,需要突出显示鼠标位置
- 开发自动化工具(如openclaw)时,需要校准操作位置
当前版本已经是V5迭代版,说明这个工具经过了多次功能完善和优化。从技术栈来看,项目使用Python开发,通过PyCharm进行编码和调试,最终使用PyInstaller等工具打包为独立的exe文件,方便在没有Python环境的Windows系统上直接运行。
2. 开发环境准备与基础配置
2.1 Python环境搭建
推荐使用Python 3.8+版本,这个版本在兼容性和稳定性方面表现良好。安装时务必勾选"Add Python to PATH"选项,这样可以在任何目录下直接运行python命令。
验证安装是否成功:
bash复制python --version
pip --version
2.2 PyCharm配置技巧
PyCharm是Python开发的利器,社区版就足够满足这个项目的需求。安装后有几个关键配置需要注意:
- 创建新项目时,选择纯Python项目模板
- 在设置中启用"Emulate terminal in output console",这样运行脚本时会更接近真实终端环境
- 安装Python插件后,配置正确的Python解释器路径
提示:如果开发多个Python项目,建议使用虚拟环境(venv)隔离依赖。在PyCharm中创建项目时可以直接勾选"New environment"选项。
2.3 必备库安装
本项目需要以下几个核心库:
bash复制pip install pyautogui # 鼠标控制与位置获取
pip install pygetwindow # 窗口管理
pip install pillow # 图像处理
pip install pyinstaller # 打包工具
3. 鼠标位置显示器核心实现
3.1 基础功能实现
创建一个mouse_tracker.py文件,实现最基本的鼠标位置显示功能:
python复制import pyautogui
import time
import sys
def main():
try:
print("鼠标位置显示器 V5 - 按Ctrl+C退出")
while True:
x, y = pyautogui.position()
print(f"\r当前鼠标位置: X={x} Y={y}", end="")
time.sleep(0.1)
except KeyboardInterrupt:
print("\n程序已退出")
if __name__ == "__main__":
main()
这段代码实现了:
- 每100毫秒获取一次鼠标位置
- 在控制台实时更新显示坐标
- 支持Ctrl+C优雅退出
3.2 增强功能实现
基础版本只能显示坐标,我们可以添加更多实用功能:
python复制import pyautogui
import time
import sys
from pygetwindow import getActiveWindow
def get_rgb_at_cursor():
x, y = pyautogui.position()
try:
return pyautogui.screenshot().getpixel((x, y))
except:
return (0, 0, 0)
def main():
try:
print("鼠标位置显示器 V5 - 按Ctrl+C退出")
while True:
x, y = pyautogui.position()
window = getActiveWindow()
window_title = window.title if window else "无活动窗口"
r, g, b = get_rgb_at_cursor()
info = (
f"坐标: X={x:<4} Y={y:<4} | "
f"颜色: R={r:<3} G={g:<3} B={b:<3} | "
f"窗口: {window_title[:30]}"
)
print(f"\r{info}", end="")
time.sleep(0.1)
except KeyboardInterrupt:
print("\n程序已退出")
if __name__ == "__main__":
main()
增强版新增了:
- 获取鼠标所在位置的RGB颜色值
- 显示当前活动窗口的标题
- 更丰富的信息展示格式
4. 使用PyInstaller打包为EXE
4.1 基础打包配置
在项目目录下创建打包脚本build.py:
python复制import PyInstaller.__main__
PyInstaller.__main__.run([
'mouse_tracker.py',
'--onefile', # 打包为单个exe
'--windowed', # 不显示控制台窗口
'--icon=app.ico', # 自定义图标
'--name=MousePositionTrackerV5' # 输出文件名
])
运行打包命令:
bash复制python build.py
打包完成后,exe文件会生成在dist目录下。
4.2 打包优化技巧
-
减小exe体积:使用UPX压缩
python复制'--upx-dir=path/to/upx', -
添加版本信息:创建version.txt文件,然后在打包参数中添加:
python复制'--version-file=version.txt', -
排除不必要的库:
python复制'--exclude-module=tkinter', -
处理资源文件:如果程序需要额外的数据文件
python复制'--add-data=assets;assets',
注意:打包时常见的问题是生成的exe文件过大。可以通过创建虚拟环境,只安装必要的依赖来优化。
5. 高级功能与openclaw集成
5.1 坐标记录与回放功能
对于openclaw等自动化工具,通常需要记录鼠标轨迹并回放。我们可以扩展程序功能:
python复制import json
from collections import deque
class MouseRecorder:
def __init__(self, max_points=1000):
self.recordings = {}
self.current_recording = None
self.buffer = deque(maxlen=max_points)
def start_recording(self, name):
self.current_recording = name
self.buffer.clear()
def stop_recording(self):
if self.current_recording:
self.recordings[self.current_recording] = list(self.buffer)
self.current_recording = None
def add_point(self, x, y, timestamp):
if self.current_recording:
self.buffer.append((x, y, timestamp))
def save_to_file(self, filename):
with open(filename, 'w') as f:
json.dump(self.recordings, f)
def load_from_file(self, filename):
with open(filename, 'r') as f:
self.recordings = json.load(f)
5.2 与openclaw的交互
openclaw通常通过配置文件或API指定操作坐标。我们的工具可以生成这样的配置文件:
python复制def generate_openclaw_config(recording_name, output_file):
if recording_name not in self.recordings:
return False
config = {
"actions": [],
"metadata": {
"created_by": "MouseTrackerV5",
"resolution": pyautogui.size()
}
}
for x, y, timestamp in self.recordings[recording_name]:
config["actions"].append({
"type": "mouse_move",
"x": x,
"y": y,
"delay": timestamp,
"comment": f"Auto-recorded at {timestamp}"
})
with open(output_file, 'w') as f:
json.dump(config, f, indent=2)
return True
6. 实际应用中的问题排查
6.1 多显示器环境处理
在多显示器环境下,坐标系统会变得复杂。我们需要正确处理这种情况:
python复制def get_scaled_position():
"""获取考虑显示器缩放后的真实位置"""
x, y = pyautogui.position()
try:
import ctypes
# 获取系统DPI缩放比例
user32 = ctypes.windll.user32
gdi32 = ctypes.windll.gdi32
dc = user32.GetDC(0)
scale = gdi32.GetDeviceCaps(dc, 88) / 96 # 88=LOGPIXELSX
user32.ReleaseDC(0, dc)
return int(x * scale), int(y * scale)
except:
return x, y
6.2 高DPI适配问题
在高DPI显示器上,程序界面可能会模糊。我们需要在打包时添加清单文件:
- 创建manifest.xml文件:
xml复制<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">True</dpiAware>
</windowsSettings>
</application>
</assembly>
- 在打包参数中添加:
python复制'--manifest=manifest.xml',
6.3 防误触安全机制
自动化工具需要防止意外操作,可以添加安全措施:
python复制# 在程序开始时设置安全暂停
pyautogui.PAUSE = 1.0 # 每个PyAutoGUI调用后暂停1秒
pyautogui.FAILSAFE = True # 启用故障安全机制
# 定义安全区域
SAFE_ZONE = (0, 0, 1920, 1080) # 假设主显示器是1080p
def is_in_safe_zone(x, y):
return (SAFE_ZONE[0] <= x <= SAFE_ZONE[2] and
SAFE_ZONE[1] <= y <= SAFE_ZONE[3])
7. 界面美化与用户体验优化
7.1 使用Tkinter创建GUI界面
虽然我们的核心功能是控制台程序,但可以添加简单的GUI:
python复制import tkinter as tk
from tkinter import ttk
class MouseTrackerApp:
def __init__(self, root):
self.root = root
self.setup_ui()
self.running = False
def setup_ui(self):
self.root.title("鼠标位置显示器 V5")
self.root.geometry("400x200")
self.position_label = ttk.Label(
self.root,
text="坐标: 等待启动...",
font=('Consolas', 14)
)
self.position_label.pack(pady=20)
self.color_display = tk.Canvas(
self.root,
width=50,
height=50,
bg='white'
)
self.color_display.pack()
self.start_button = ttk.Button(
self.root,
text="启动跟踪",
command=self.toggle_tracking
)
self.start_button.pack(pady=10)
self.record_button = ttk.Button(
self.root,
text="开始录制",
command=self.start_recording,
state=tk.DISABLED
)
self.record_button.pack(pady=5)
def toggle_tracking(self):
self.running = not self.running
if self.running:
self.start_button.config(text="停止跟踪")
self.record_button.config(state=tk.NORMAL)
self.update_position()
else:
self.start_button.config(text="启动跟踪")
self.record_button.config(state=tk.DISABLED)
def update_position(self):
if self.running:
x, y = pyautogui.position()
r, g, b = get_rgb_at_cursor()
self.position_label.config(
text=f"坐标: X={x} Y={y}\n颜色: R={r} G={g} B={b}"
)
self.color_display.config(bg=f'#{r:02x}{g:02x}{b:02x}')
self.root.after(100, self.update_position)
def start_recording(self):
pass # 实现录制逻辑
if __name__ == "__main__":
root = tk.Tk()
app = MouseTrackerApp(root)
root.mainloop()
7.2 系统托盘图标实现
对于后台运行的工具,系统托盘是更好的选择:
python复制import pystray
from PIL import Image
def create_tray_icon():
image = Image.new('RGB', (64, 64), 'white')
icon = pystray.Icon(
"mouse_tracker",
icon=image,
title="鼠标位置显示器 V5",
menu=pystray.Menu(
pystray.MenuItem("显示坐标", show_position),
pystray.MenuItem("退出", exit_app)
)
)
return icon
def show_position():
# 实现显示坐标窗口的逻辑
pass
def exit_app(icon):
icon.stop()
# 在后台线程中运行
tray_icon = create_tray_icon()
tray_icon.run()
8. 性能优化与代码重构
8.1 使用多线程提高响应速度
长时间运行的鼠标位置检测可能会阻塞主线程,使用多线程优化:
python复制import threading
from queue import Queue
class MouseTrackerThread(threading.Thread):
def __init__(self, update_queue):
super().__init__()
self.update_queue = update_queue
self._stop_event = threading.Event()
def run(self):
while not self._stop_event.is_set():
x, y = pyautogui.position()
timestamp = time.time()
self.update_queue.put(('position', (x, y, timestamp)))
time.sleep(0.05)
def stop(self):
self._stop_event.set()
# 在主程序中使用
update_queue = Queue()
tracker_thread = MouseTrackerThread(update_queue)
tracker_thread.start()
# 处理队列中的更新
while True:
item = update_queue.get()
if item[0] == 'position':
x, y, timestamp = item[1]
# 更新显示...
8.2 使用类重构代码
将功能封装成类,提高代码可维护性:
python复制class MousePositionTracker:
def __init__(self, version="V5"):
self.version = version
self.recording = False
self.recorded_points = []
self.listeners = []
def add_listener(self, callback):
"""添加位置更新监听器"""
self.listeners.append(callback)
def remove_listener(self, callback):
"""移除位置更新监听器"""
self.listeners.remove(callback)
def start_tracking(self):
"""开始跟踪鼠标位置"""
self.tracking = True
self._track_loop()
def stop_tracking(self):
"""停止跟踪"""
self.tracking = False
def start_recording(self):
"""开始录制鼠标轨迹"""
self.recording = True
self.recorded_points = []
def stop_recording(self):
"""停止录制"""
self.recording = False
return self.recorded_points
def _track_loop(self):
while self.tracking:
x, y = pyautogui.position()
timestamp = time.time()
# 通知所有监听器
for listener in self.listeners:
listener(x, y, timestamp)
# 如果正在录制,保存点
if self.recording:
self.recorded_points.append((x, y, timestamp))
time.sleep(0.05)
9. 版本迭代与功能规划
9.1 V5版本新增功能
作为第五个迭代版本,V5应该包含以下改进:
- 多显示器支持
- DPI缩放感知
- 轨迹录制与回放
- openclaw配置文件导出
- 系统托盘支持
- 性能优化
9.2 未来版本规划
可以考虑在后续版本中添加:
- 热键支持:通过快捷键开始/停止录制
- 坐标偏移校准:针对不同分辨率的设备
- 操作回放速度控制
- 脚本生成:直接生成Python自动化脚本
- 插件系统:支持扩展功能
10. 实际应用案例
10.1 游戏自动化开发
假设我们要为某游戏开发自动采集资源的脚本:
- 使用鼠标位置显示器记录资源点的坐标
- 记录移动路径和点击位置
- 导出为openclaw配置文件
- 设置定时执行
10.2 UI自动化测试
在测试Web应用时:
- 记录测试流程中的关键操作点
- 验证在不同分辨率下的坐标偏移
- 生成测试脚本
- 集成到CI/CD流程
10.3 教学演示制作
创建软件操作教程时:
- 录制操作过程
- 添加注释和停顿
- 生成演示脚本
- 结合屏幕录制制作完整教程
11. 打包发布与用户指南
11.1 创建安装程序
使用Inno Setup等工具创建专业的安装程序:
- 编写ISS脚本:
iss复制[Setup]
AppName=鼠标位置显示器
AppVersion=5.0
DefaultDirName={pf}\MousePositionTracker
DefaultGroupName=鼠标位置显示器
OutputDir=output
OutputBaseFilename=MousePositionTrackerV5Setup
Compression=lzma
SolidCompression=yes
[Files]
Source: "dist\MousePositionTrackerV5.exe"; DestDir: "{app}"
[Icons]
Name: "{group}\鼠标位置显示器 V5"; Filename: "{app}\MousePositionTrackerV5.exe"
- 编译生成安装包
11.2 编写用户手册
创建简单的README.md:
markdown复制# 鼠标位置显示器 V5
## 功能特性
- 实时显示鼠标坐标
- 支持多显示器环境
- 轨迹录制与回放
- 导出openclaw配置文件
## 使用说明
### 基本使用
1. 双击运行MousePositionTrackerV5.exe
2. 系统托盘会出现程序图标
3. 右键菜单选择"显示坐标"打开主窗口
### 快捷键
- Ctrl+R 开始/停止录制
- Ctrl+S 保存录制轨迹
- Ctrl+Q 退出程序
## 常见问题
Q: 程序在高DPI屏幕上显示模糊
A: 右键exe文件 > 属性 > 兼容性 > 更改高DPI设置 > 勾选"替代高DPI缩放行为"
12. 项目总结与经验分享
开发这类工具时,我积累了几个重要经验:
-
坐标系统复杂性:不同显示器、不同DPI设置下的坐标处理是个大坑。一定要在实际环境中充分测试。
-
打包依赖问题:PyInstaller打包时经常会漏掉一些隐式依赖。使用
--hidden-import参数显式指定,或者在干净环境中打包。 -
防误触机制:自动化工具必须要有安全措施,比如设置移动边界、添加延迟等,防止失控造成损失。
-
性能考量:频繁获取鼠标位置会影响系统性能。适当调整采样频率,使用多线程分离UI和采集逻辑。
-
跨平台兼容性:如果考虑跨平台,需要注意不同操作系统下获取鼠标位置的API差异。可以考虑使用
pynput等跨平台库。
这个项目虽然不大,但涵盖了Python开发的完整流程:从需求分析、编码实现、调试测试到打包发布。对于想学习Python实际应用的朋友来说,是个很好的练手项目。
