# xtdamo
[](https://github.com/sandorn/xtdamo)
[](https://www.python.org/downloads/)
[](LICENSE)
xtdamo 是一个基于大漠插件(Dm) 的现代化封装库,用于自动化操作,包括窗口管理、鼠标控制、键盘模拟、图像识别、文本查找等功能。适用于游戏脚本、自动化测试、RPA 等场景。
## ✨ 特性亮点
### 🏗️ 现代化架构设计
- **分层架构**: 清晰的 `DmExcute -> ApiProxy -> CoreEngine` 三层设计
- **智能路由**: 自动选择最佳方法实现,无需关心底层细节
- **模块化**: `Key`、`Mouse` 独立模块,职责明确
- **向后兼容**: 支持旧版本代码无缝迁移
### 🛡️ 健壮的错误处理
- **参数验证**: 完整的参数范围检查和类型验证
- **友好错误**: 详细的错误信息和诊断建议
- **异常安全**: 完善的异常处理机制
### 📚 完整的文档支持
- **Google Style**: 所有方法都有详细的文档字符串
- **类型注解**: 完整的类型提示,IDE 智能提示友好
- **示例丰富**: 每个功能都有实用的代码示例
### 🚀 增强功能
- **安全点击**: `safe_click` 带随机延迟,防检测
- **便利属性**: `position` 属性快速获取/设置鼠标位置
- **高级操作**: 支持持续时间的点击、拖拽等复杂操作
## 简介
xtdamo 提供了对大漠插件的高级封装,简化了与窗口、鼠标、键盘和图像识别相关的操作。主要功能包括:
- **窗口管理**: 窗口查找、绑定、属性获取
- **鼠标操作**: 移动、点击、拖拽、滚轮
- **键盘模拟**: 按键、组合键、文本输入
- **图像识别**: 图像查找、颜色识别
- **文本识别**: 文字查找、OCR
- **高级功能**: 文件操作、注册表操作
## 安装
### 系统要求
- **Python 3.8+ (32 位版本)** - 大漠插件仅支持 32 位 Python 环境
- Windows 操作系统
- 大漠插件(dm.dll)
> **重要提示**: 大漠插件只能在 32 位 Python 环境下运行,请确保使用 32 位 Python 版本。
### 安装方法
1. **创建 32 位 Python 虚拟环境**:
```bash
# 确保使用32位Python创建虚拟环境
python -m venv .venv --python=python3.12-32 # 或指定32位Python路径
.venv\Scripts\activate # Windows
```
2. **从源码安装**:
```bash
git clone https://github.com/sandorn/xtdamo.git
cd xtdamo
pip install -e .
```
3. **从 PyPI 安装**(计划中):
```bash
pip install xtdamo
```
> **注意**: 请确保在 32 位 Python 环境中安装和运行项目。
### 大漠插件配置
将大漠插件(dm.dll)放置在项目目录中,或通过环境变量指定路径:
```bash
# 设置大漠插件认证信息(可选)
set DM_REG_CODE=your_registration_code
set DM_VER_INFO=your_version_info
```
## 架构设计
xtdamo 采用清晰的分层架构设计,确保代码的可维护性和可扩展性:
```
┌─────────────────────────────────────┐
│ DmExcute (主入口) │
│ - 统一的调用接口 │
│ - 自动方法路由 │
└──────────────┬──────────────────────┘
│
├──────────────────────┐
│ │
┌───────▼────────┐ ┌───────▼────────┐
│ ApiProxy │ │ CoreEngine │
│ (高级接口层) │───>│ (核心引擎层) │
│ │ │ │
│ - 中文友好API │ │ - 底层核心方法 │
│ - 智能错误处理 │ │ - 直接封装DM │
│ - 自动日志记录 │ │ - 基础功能实现 │
└────────────────┘ └────────────────┘
```
### 核心特性
- **分层架构**: 清晰的层次划分,职责明确
- **智能路由**: 自动选择最合适的实现方法
- **向后兼容**: 保持对旧代码的兼容性
- **易于扩展**: 模块化设计,方便功能扩展
更多架构细节请参考 [架构更新说明](docs/architecture_update.md)。
## 📖 使用示例
### 快速开始
```python
from xtdamo import DmExcute
# 初始化(自动注册大漠插件)
dm = DmExcute()
# 查看版本信息
print(f"版本: {dm.ver()}")
print(f"库版本: {dm.__version__}") # 输出: 0.2.0
```
### 窗口操作
```python
# 查找窗口
hwnd = dm.FindWindow("", "记事本")
if hwnd == 0:
print("未找到窗口")
exit(1)
# 绑定窗口(高级接口,带参数验证)
try:
dm.绑定窗口(
hwnd,
display='gdi', # 显示模式
mouse='windows3', # 鼠标模式
keypad='windows', # 键盘模式
mode=101 # 绑定模式
)
print("绑定成功!")
except ValueError as e:
print(f"参数错误: {e}")
except AssertionError as e:
print(f"绑定失败: {e}")
# 使用默认配置绑定(推荐)
dm.绑定窗口(hwnd) # 使用默认参数
```
### 鼠标操作(多种方式)
```python
# 方式1: 通过 DmExcute 主入口(自动路由)
dm.MoveTo(100, 200) # 移动鼠标
dm.LeftClick() # 左键点击
# 方式2: 使用便利属性
x, y = dm.Mouse.position # 获取当前位置
dm.Mouse.position = (500, 300) # 设置位置
# 方式3: 使用增强方法
dm.Mouse.safe_click(300, 400, auto_reset_pos=True) # 安全点击
dm.Mouse.click_left(100, 200, t=1.0) # 长按1秒
# 方式4: 拖拽操作
dm.Mouse.MoveTo(100, 100)
dm.Mouse.LeftDown()
dm.Mouse.MoveTo(200, 200)
dm.Mouse.LeftUp()
```
### 键盘操作
```python
# 通过 DmExcute 主入口
dm.KeyPressStr('Hello World') # 输入文本
dm.KeyPress(13) # 按回车键(VK_RETURN)
# 使用 VirtualKeys 常量
from xtdamo.time_utils import VirtualKeys
dm.Key.KeyPress(VirtualKeys.ENTER)
dm.Key.KeyPress(VirtualKeys.ESC)
# 组合键操作
dm.Key.KeyDown(VirtualKeys.CTRL) # 按下Ctrl
dm.Key.KeyPress(ord('C')) # 按C键
dm.Key.KeyUp(VirtualKeys.CTRL) # 释放Ctrl
# 等待按键
if dm.Key.WaitKey(VirtualKeys.ESC, 5000):
print("用户按下了ESC键")
```
### 图像识别与操作
```python
# 高级接口 - 找图并点击
success = dm.找图单击(0, 0, 1920, 1080, 'button.bmp', '000000', 0.9)
if success:
print("找到并点击成功")
# 找图直到消失
dm.找图单击至消失(0, 0, 800, 600, 'close.bmp', max_retries=10)
# 获取坐标
found, x, y = dm.找图返回坐标(0, 0, 1920, 1080, 'target.bmp')
if found:
print(f"图像位置: ({x}, {y})")
dm.Mouse.safe_click(x, y)
```
### 文字识别与操作
```python
# 找字并点击
success = dm.找字单击(0, 0, 800, 600, '开始游戏', 'FFFFFF', 0.9)
# 简易识字
text = dm.简易识字(100, 100, 300, 200, 'FFFFFF', 0.9)
print(f"识别到的文字: {text}")
# 找字返回坐标
found, x, y = dm.找字返回坐标(0, 0, 800, 600, '确定', 'FFFFFF', 0.9)
if found:
dm.Mouse.MoveTo(x, y)
dm.Mouse.LeftClick()
```
### 智能查找(渐开螺旋)
```python
# 从中心点向外螺旋查找鼠标
found, x, y = dm.圆形渐开找鼠标(
center_x=500,
center_y=400,
max_radius=200,
pic_name='cursor.bmp'
)
if found:
print(f"鼠标图片位置: ({x}, {y})")
```
### 完整示例 - 自动化脚本
```python
from xtdamo import DmExcute
from xtdamo.time_utils import sleep, VirtualKeys
def main():
# 初始化
dm = DmExcute()
print(f"xtdamo 版本: {dm.__version__}")
# 查找并绑定窗口
hwnd = dm.FindWindow("", "目标程序")
if hwnd == 0:
print("未找到窗口")
return
# 绑定窗口(使用默认配置)
dm.绑定窗口(hwnd)
print("窗口绑定成功")
# 执行自动化任务
try:
# 点击开始按钮
if dm.找图单击(0, 0, 800, 600, 'start_button.bmp'):
print("点击开始按钮成功")
sleep(1)
# 输入用户名
dm.KeyPressStr('username')
dm.KeyPress(VirtualKeys.TAB)
# 输入密码
dm.KeyPressStr('password')
dm.KeyPress(VirtualKeys.ENTER)
# 等待登录完成(找图确认)
sleep(2)
if dm.简易找图(0, 0, 800, 600, 'login_success.bmp'):
print("登录成功!")
finally:
# 解绑窗口
dm.解绑窗口()
print("窗口已解绑")
if __name__ == '__main__':
main()
```
## 贡献
欢迎贡献代码或提出建议!请参考 [贡献指南](CONTRIBUTING.md) 获取更多信息。
## 许可证
本项目遵循 [MIT 许可证](LICENSE)。
Raw data
{
"_id": null,
"home_page": null,
"name": "xtdamo",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "automation, dm-plugin, mouse, keyboard, image-recognition",
"author": null,
"author_email": "sandorn <sandorn@live.cn>",
"download_url": "https://files.pythonhosted.org/packages/b5/6e/1205187ea3cb88a9e02b16959b143e709bd885f559addcf7fcb5318cb440/xtdamo-0.2.0.tar.gz",
"platform": null,
"description": "# xtdamo\r\n\r\n[](https://github.com/sandorn/xtdamo)\r\n[](https://www.python.org/downloads/)\r\n[](LICENSE)\r\n\r\nxtdamo \u662f\u4e00\u4e2a\u57fa\u4e8e\u5927\u6f20\u63d2\u4ef6(Dm) \u7684\u73b0\u4ee3\u5316\u5c01\u88c5\u5e93\uff0c\u7528\u4e8e\u81ea\u52a8\u5316\u64cd\u4f5c\uff0c\u5305\u62ec\u7a97\u53e3\u7ba1\u7406\u3001\u9f20\u6807\u63a7\u5236\u3001\u952e\u76d8\u6a21\u62df\u3001\u56fe\u50cf\u8bc6\u522b\u3001\u6587\u672c\u67e5\u627e\u7b49\u529f\u80fd\u3002\u9002\u7528\u4e8e\u6e38\u620f\u811a\u672c\u3001\u81ea\u52a8\u5316\u6d4b\u8bd5\u3001RPA \u7b49\u573a\u666f\u3002\r\n\r\n## \u2728 \u7279\u6027\u4eae\u70b9\r\n\r\n### \ud83c\udfd7\ufe0f \u73b0\u4ee3\u5316\u67b6\u6784\u8bbe\u8ba1\r\n\r\n- **\u5206\u5c42\u67b6\u6784**: \u6e05\u6670\u7684 `DmExcute -> ApiProxy -> CoreEngine` \u4e09\u5c42\u8bbe\u8ba1\r\n- **\u667a\u80fd\u8def\u7531**: \u81ea\u52a8\u9009\u62e9\u6700\u4f73\u65b9\u6cd5\u5b9e\u73b0\uff0c\u65e0\u9700\u5173\u5fc3\u5e95\u5c42\u7ec6\u8282\r\n- **\u6a21\u5757\u5316**: `Key`\u3001`Mouse` \u72ec\u7acb\u6a21\u5757\uff0c\u804c\u8d23\u660e\u786e\r\n- **\u5411\u540e\u517c\u5bb9**: \u652f\u6301\u65e7\u7248\u672c\u4ee3\u7801\u65e0\u7f1d\u8fc1\u79fb\r\n\r\n### \ud83d\udee1\ufe0f \u5065\u58ee\u7684\u9519\u8bef\u5904\u7406\r\n\r\n- **\u53c2\u6570\u9a8c\u8bc1**: \u5b8c\u6574\u7684\u53c2\u6570\u8303\u56f4\u68c0\u67e5\u548c\u7c7b\u578b\u9a8c\u8bc1\r\n- **\u53cb\u597d\u9519\u8bef**: \u8be6\u7ec6\u7684\u9519\u8bef\u4fe1\u606f\u548c\u8bca\u65ad\u5efa\u8bae\r\n- **\u5f02\u5e38\u5b89\u5168**: \u5b8c\u5584\u7684\u5f02\u5e38\u5904\u7406\u673a\u5236\r\n\r\n### \ud83d\udcda \u5b8c\u6574\u7684\u6587\u6863\u652f\u6301\r\n\r\n- **Google Style**: \u6240\u6709\u65b9\u6cd5\u90fd\u6709\u8be6\u7ec6\u7684\u6587\u6863\u5b57\u7b26\u4e32\r\n- **\u7c7b\u578b\u6ce8\u89e3**: \u5b8c\u6574\u7684\u7c7b\u578b\u63d0\u793a\uff0cIDE \u667a\u80fd\u63d0\u793a\u53cb\u597d\r\n- **\u793a\u4f8b\u4e30\u5bcc**: \u6bcf\u4e2a\u529f\u80fd\u90fd\u6709\u5b9e\u7528\u7684\u4ee3\u7801\u793a\u4f8b\r\n\r\n### \ud83d\ude80 \u589e\u5f3a\u529f\u80fd\r\n\r\n- **\u5b89\u5168\u70b9\u51fb**: `safe_click` \u5e26\u968f\u673a\u5ef6\u8fdf\uff0c\u9632\u68c0\u6d4b\r\n- **\u4fbf\u5229\u5c5e\u6027**: `position` \u5c5e\u6027\u5feb\u901f\u83b7\u53d6/\u8bbe\u7f6e\u9f20\u6807\u4f4d\u7f6e\r\n- **\u9ad8\u7ea7\u64cd\u4f5c**: \u652f\u6301\u6301\u7eed\u65f6\u95f4\u7684\u70b9\u51fb\u3001\u62d6\u62fd\u7b49\u590d\u6742\u64cd\u4f5c\r\n\r\n## \u7b80\u4ecb\r\n\r\nxtdamo \u63d0\u4f9b\u4e86\u5bf9\u5927\u6f20\u63d2\u4ef6\u7684\u9ad8\u7ea7\u5c01\u88c5\uff0c\u7b80\u5316\u4e86\u4e0e\u7a97\u53e3\u3001\u9f20\u6807\u3001\u952e\u76d8\u548c\u56fe\u50cf\u8bc6\u522b\u76f8\u5173\u7684\u64cd\u4f5c\u3002\u4e3b\u8981\u529f\u80fd\u5305\u62ec\uff1a\r\n\r\n- **\u7a97\u53e3\u7ba1\u7406**: \u7a97\u53e3\u67e5\u627e\u3001\u7ed1\u5b9a\u3001\u5c5e\u6027\u83b7\u53d6\r\n- **\u9f20\u6807\u64cd\u4f5c**: \u79fb\u52a8\u3001\u70b9\u51fb\u3001\u62d6\u62fd\u3001\u6eda\u8f6e\r\n- **\u952e\u76d8\u6a21\u62df**: \u6309\u952e\u3001\u7ec4\u5408\u952e\u3001\u6587\u672c\u8f93\u5165\r\n- **\u56fe\u50cf\u8bc6\u522b**: \u56fe\u50cf\u67e5\u627e\u3001\u989c\u8272\u8bc6\u522b\r\n- **\u6587\u672c\u8bc6\u522b**: \u6587\u5b57\u67e5\u627e\u3001OCR\r\n- **\u9ad8\u7ea7\u529f\u80fd**: \u6587\u4ef6\u64cd\u4f5c\u3001\u6ce8\u518c\u8868\u64cd\u4f5c\r\n\r\n## \u5b89\u88c5\r\n\r\n### \u7cfb\u7edf\u8981\u6c42\r\n\r\n- **Python 3.8+ (32 \u4f4d\u7248\u672c)** - \u5927\u6f20\u63d2\u4ef6\u4ec5\u652f\u6301 32 \u4f4d Python \u73af\u5883\r\n- Windows \u64cd\u4f5c\u7cfb\u7edf\r\n- \u5927\u6f20\u63d2\u4ef6\uff08dm.dll\uff09\r\n\r\n> **\u91cd\u8981\u63d0\u793a**: \u5927\u6f20\u63d2\u4ef6\u53ea\u80fd\u5728 32 \u4f4d Python \u73af\u5883\u4e0b\u8fd0\u884c\uff0c\u8bf7\u786e\u4fdd\u4f7f\u7528 32 \u4f4d Python \u7248\u672c\u3002\r\n\r\n### \u5b89\u88c5\u65b9\u6cd5\r\n\r\n1. **\u521b\u5efa 32 \u4f4d Python \u865a\u62df\u73af\u5883**\uff1a\r\n\r\n```bash\r\n# \u786e\u4fdd\u4f7f\u752832\u4f4dPython\u521b\u5efa\u865a\u62df\u73af\u5883\r\npython -m venv .venv --python=python3.12-32 # \u6216\u6307\u5b9a32\u4f4dPython\u8def\u5f84\r\n.venv\\Scripts\\activate # Windows\r\n```\r\n\r\n2. **\u4ece\u6e90\u7801\u5b89\u88c5**\uff1a\r\n\r\n```bash\r\ngit clone https://github.com/sandorn/xtdamo.git\r\ncd xtdamo\r\npip install -e .\r\n```\r\n\r\n3. **\u4ece PyPI \u5b89\u88c5**\uff08\u8ba1\u5212\u4e2d\uff09\uff1a\r\n\r\n```bash\r\npip install xtdamo\r\n```\r\n\r\n> **\u6ce8\u610f**: \u8bf7\u786e\u4fdd\u5728 32 \u4f4d Python \u73af\u5883\u4e2d\u5b89\u88c5\u548c\u8fd0\u884c\u9879\u76ee\u3002\r\n\r\n### \u5927\u6f20\u63d2\u4ef6\u914d\u7f6e\r\n\r\n\u5c06\u5927\u6f20\u63d2\u4ef6\uff08dm.dll\uff09\u653e\u7f6e\u5728\u9879\u76ee\u76ee\u5f55\u4e2d\uff0c\u6216\u901a\u8fc7\u73af\u5883\u53d8\u91cf\u6307\u5b9a\u8def\u5f84\uff1a\r\n\r\n```bash\r\n# \u8bbe\u7f6e\u5927\u6f20\u63d2\u4ef6\u8ba4\u8bc1\u4fe1\u606f\uff08\u53ef\u9009\uff09\r\nset DM_REG_CODE=your_registration_code\r\nset DM_VER_INFO=your_version_info\r\n```\r\n\r\n## \u67b6\u6784\u8bbe\u8ba1\r\n\r\nxtdamo \u91c7\u7528\u6e05\u6670\u7684\u5206\u5c42\u67b6\u6784\u8bbe\u8ba1\uff0c\u786e\u4fdd\u4ee3\u7801\u7684\u53ef\u7ef4\u62a4\u6027\u548c\u53ef\u6269\u5c55\u6027\uff1a\r\n\r\n```\r\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\r\n\u2502 DmExcute (\u4e3b\u5165\u53e3) \u2502\r\n\u2502 - \u7edf\u4e00\u7684\u8c03\u7528\u63a5\u53e3 \u2502\r\n\u2502 - \u81ea\u52a8\u65b9\u6cd5\u8def\u7531 \u2502\r\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\r\n \u2502\r\n \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\r\n \u2502 \u2502\r\n \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u25bc\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u25bc\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\r\n \u2502 ApiProxy \u2502 \u2502 CoreEngine \u2502\r\n \u2502 (\u9ad8\u7ea7\u63a5\u53e3\u5c42) \u2502\u2500\u2500\u2500>\u2502 (\u6838\u5fc3\u5f15\u64ce\u5c42) \u2502\r\n \u2502 \u2502 \u2502 \u2502\r\n \u2502 - \u4e2d\u6587\u53cb\u597dAPI \u2502 \u2502 - \u5e95\u5c42\u6838\u5fc3\u65b9\u6cd5 \u2502\r\n \u2502 - \u667a\u80fd\u9519\u8bef\u5904\u7406 \u2502 \u2502 - \u76f4\u63a5\u5c01\u88c5DM \u2502\r\n \u2502 - \u81ea\u52a8\u65e5\u5fd7\u8bb0\u5f55 \u2502 \u2502 - \u57fa\u7840\u529f\u80fd\u5b9e\u73b0 \u2502\r\n \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\r\n```\r\n\r\n### \u6838\u5fc3\u7279\u6027\r\n\r\n- **\u5206\u5c42\u67b6\u6784**: \u6e05\u6670\u7684\u5c42\u6b21\u5212\u5206\uff0c\u804c\u8d23\u660e\u786e\r\n- **\u667a\u80fd\u8def\u7531**: \u81ea\u52a8\u9009\u62e9\u6700\u5408\u9002\u7684\u5b9e\u73b0\u65b9\u6cd5\r\n- **\u5411\u540e\u517c\u5bb9**: \u4fdd\u6301\u5bf9\u65e7\u4ee3\u7801\u7684\u517c\u5bb9\u6027\r\n- **\u6613\u4e8e\u6269\u5c55**: \u6a21\u5757\u5316\u8bbe\u8ba1\uff0c\u65b9\u4fbf\u529f\u80fd\u6269\u5c55\r\n\r\n\u66f4\u591a\u67b6\u6784\u7ec6\u8282\u8bf7\u53c2\u8003 [\u67b6\u6784\u66f4\u65b0\u8bf4\u660e](docs/architecture_update.md)\u3002\r\n\r\n## \ud83d\udcd6 \u4f7f\u7528\u793a\u4f8b\r\n\r\n### \u5feb\u901f\u5f00\u59cb\r\n\r\n```python\r\nfrom xtdamo import DmExcute\r\n\r\n# \u521d\u59cb\u5316\uff08\u81ea\u52a8\u6ce8\u518c\u5927\u6f20\u63d2\u4ef6\uff09\r\ndm = DmExcute()\r\n\r\n# \u67e5\u770b\u7248\u672c\u4fe1\u606f\r\nprint(f\"\u7248\u672c: {dm.ver()}\")\r\nprint(f\"\u5e93\u7248\u672c: {dm.__version__}\") # \u8f93\u51fa: 0.2.0\r\n```\r\n\r\n### \u7a97\u53e3\u64cd\u4f5c\r\n\r\n```python\r\n# \u67e5\u627e\u7a97\u53e3\r\nhwnd = dm.FindWindow(\"\", \"\u8bb0\u4e8b\u672c\")\r\nif hwnd == 0:\r\n print(\"\u672a\u627e\u5230\u7a97\u53e3\")\r\n exit(1)\r\n\r\n# \u7ed1\u5b9a\u7a97\u53e3\uff08\u9ad8\u7ea7\u63a5\u53e3\uff0c\u5e26\u53c2\u6570\u9a8c\u8bc1\uff09\r\ntry:\r\n dm.\u7ed1\u5b9a\u7a97\u53e3(\r\n hwnd,\r\n display='gdi', # \u663e\u793a\u6a21\u5f0f\r\n mouse='windows3', # \u9f20\u6807\u6a21\u5f0f\r\n keypad='windows', # \u952e\u76d8\u6a21\u5f0f\r\n mode=101 # \u7ed1\u5b9a\u6a21\u5f0f\r\n )\r\n print(\"\u7ed1\u5b9a\u6210\u529f\uff01\")\r\nexcept ValueError as e:\r\n print(f\"\u53c2\u6570\u9519\u8bef: {e}\")\r\nexcept AssertionError as e:\r\n print(f\"\u7ed1\u5b9a\u5931\u8d25: {e}\")\r\n\r\n# \u4f7f\u7528\u9ed8\u8ba4\u914d\u7f6e\u7ed1\u5b9a\uff08\u63a8\u8350\uff09\r\ndm.\u7ed1\u5b9a\u7a97\u53e3(hwnd) # \u4f7f\u7528\u9ed8\u8ba4\u53c2\u6570\r\n```\r\n\r\n### \u9f20\u6807\u64cd\u4f5c\uff08\u591a\u79cd\u65b9\u5f0f\uff09\r\n\r\n```python\r\n# \u65b9\u5f0f1: \u901a\u8fc7 DmExcute \u4e3b\u5165\u53e3\uff08\u81ea\u52a8\u8def\u7531\uff09\r\ndm.MoveTo(100, 200) # \u79fb\u52a8\u9f20\u6807\r\ndm.LeftClick() # \u5de6\u952e\u70b9\u51fb\r\n\r\n# \u65b9\u5f0f2: \u4f7f\u7528\u4fbf\u5229\u5c5e\u6027\r\nx, y = dm.Mouse.position # \u83b7\u53d6\u5f53\u524d\u4f4d\u7f6e\r\ndm.Mouse.position = (500, 300) # \u8bbe\u7f6e\u4f4d\u7f6e\r\n\r\n# \u65b9\u5f0f3: \u4f7f\u7528\u589e\u5f3a\u65b9\u6cd5\r\ndm.Mouse.safe_click(300, 400, auto_reset_pos=True) # \u5b89\u5168\u70b9\u51fb\r\ndm.Mouse.click_left(100, 200, t=1.0) # \u957f\u63091\u79d2\r\n\r\n# \u65b9\u5f0f4: \u62d6\u62fd\u64cd\u4f5c\r\ndm.Mouse.MoveTo(100, 100)\r\ndm.Mouse.LeftDown()\r\ndm.Mouse.MoveTo(200, 200)\r\ndm.Mouse.LeftUp()\r\n```\r\n\r\n### \u952e\u76d8\u64cd\u4f5c\r\n\r\n```python\r\n# \u901a\u8fc7 DmExcute \u4e3b\u5165\u53e3\r\ndm.KeyPressStr('Hello World') # \u8f93\u5165\u6587\u672c\r\ndm.KeyPress(13) # \u6309\u56de\u8f66\u952e\uff08VK_RETURN\uff09\r\n\r\n# \u4f7f\u7528 VirtualKeys \u5e38\u91cf\r\nfrom xtdamo.time_utils import VirtualKeys\r\ndm.Key.KeyPress(VirtualKeys.ENTER)\r\ndm.Key.KeyPress(VirtualKeys.ESC)\r\n\r\n# \u7ec4\u5408\u952e\u64cd\u4f5c\r\ndm.Key.KeyDown(VirtualKeys.CTRL) # \u6309\u4e0bCtrl\r\ndm.Key.KeyPress(ord('C')) # \u6309C\u952e\r\ndm.Key.KeyUp(VirtualKeys.CTRL) # \u91ca\u653eCtrl\r\n\r\n# \u7b49\u5f85\u6309\u952e\r\nif dm.Key.WaitKey(VirtualKeys.ESC, 5000):\r\n print(\"\u7528\u6237\u6309\u4e0b\u4e86ESC\u952e\")\r\n```\r\n\r\n### \u56fe\u50cf\u8bc6\u522b\u4e0e\u64cd\u4f5c\r\n\r\n```python\r\n# \u9ad8\u7ea7\u63a5\u53e3 - \u627e\u56fe\u5e76\u70b9\u51fb\r\nsuccess = dm.\u627e\u56fe\u5355\u51fb(0, 0, 1920, 1080, 'button.bmp', '000000', 0.9)\r\nif success:\r\n print(\"\u627e\u5230\u5e76\u70b9\u51fb\u6210\u529f\")\r\n\r\n# \u627e\u56fe\u76f4\u5230\u6d88\u5931\r\ndm.\u627e\u56fe\u5355\u51fb\u81f3\u6d88\u5931(0, 0, 800, 600, 'close.bmp', max_retries=10)\r\n\r\n# \u83b7\u53d6\u5750\u6807\r\nfound, x, y = dm.\u627e\u56fe\u8fd4\u56de\u5750\u6807(0, 0, 1920, 1080, 'target.bmp')\r\nif found:\r\n print(f\"\u56fe\u50cf\u4f4d\u7f6e: ({x}, {y})\")\r\n dm.Mouse.safe_click(x, y)\r\n```\r\n\r\n### \u6587\u5b57\u8bc6\u522b\u4e0e\u64cd\u4f5c\r\n\r\n```python\r\n# \u627e\u5b57\u5e76\u70b9\u51fb\r\nsuccess = dm.\u627e\u5b57\u5355\u51fb(0, 0, 800, 600, '\u5f00\u59cb\u6e38\u620f', 'FFFFFF', 0.9)\r\n\r\n# \u7b80\u6613\u8bc6\u5b57\r\ntext = dm.\u7b80\u6613\u8bc6\u5b57(100, 100, 300, 200, 'FFFFFF', 0.9)\r\nprint(f\"\u8bc6\u522b\u5230\u7684\u6587\u5b57: {text}\")\r\n\r\n# \u627e\u5b57\u8fd4\u56de\u5750\u6807\r\nfound, x, y = dm.\u627e\u5b57\u8fd4\u56de\u5750\u6807(0, 0, 800, 600, '\u786e\u5b9a', 'FFFFFF', 0.9)\r\nif found:\r\n dm.Mouse.MoveTo(x, y)\r\n dm.Mouse.LeftClick()\r\n```\r\n\r\n### \u667a\u80fd\u67e5\u627e\uff08\u6e10\u5f00\u87ba\u65cb\uff09\r\n\r\n```python\r\n# \u4ece\u4e2d\u5fc3\u70b9\u5411\u5916\u87ba\u65cb\u67e5\u627e\u9f20\u6807\r\nfound, x, y = dm.\u5706\u5f62\u6e10\u5f00\u627e\u9f20\u6807(\r\n center_x=500,\r\n center_y=400,\r\n max_radius=200,\r\n pic_name='cursor.bmp'\r\n)\r\nif found:\r\n print(f\"\u9f20\u6807\u56fe\u7247\u4f4d\u7f6e: ({x}, {y})\")\r\n```\r\n\r\n### \u5b8c\u6574\u793a\u4f8b - \u81ea\u52a8\u5316\u811a\u672c\r\n\r\n```python\r\nfrom xtdamo import DmExcute\r\nfrom xtdamo.time_utils import sleep, VirtualKeys\r\n\r\ndef main():\r\n # \u521d\u59cb\u5316\r\n dm = DmExcute()\r\n print(f\"xtdamo \u7248\u672c: {dm.__version__}\")\r\n\r\n # \u67e5\u627e\u5e76\u7ed1\u5b9a\u7a97\u53e3\r\n hwnd = dm.FindWindow(\"\", \"\u76ee\u6807\u7a0b\u5e8f\")\r\n if hwnd == 0:\r\n print(\"\u672a\u627e\u5230\u7a97\u53e3\")\r\n return\r\n\r\n # \u7ed1\u5b9a\u7a97\u53e3\uff08\u4f7f\u7528\u9ed8\u8ba4\u914d\u7f6e\uff09\r\n dm.\u7ed1\u5b9a\u7a97\u53e3(hwnd)\r\n print(\"\u7a97\u53e3\u7ed1\u5b9a\u6210\u529f\")\r\n\r\n # \u6267\u884c\u81ea\u52a8\u5316\u4efb\u52a1\r\n try:\r\n # \u70b9\u51fb\u5f00\u59cb\u6309\u94ae\r\n if dm.\u627e\u56fe\u5355\u51fb(0, 0, 800, 600, 'start_button.bmp'):\r\n print(\"\u70b9\u51fb\u5f00\u59cb\u6309\u94ae\u6210\u529f\")\r\n sleep(1)\r\n\r\n # \u8f93\u5165\u7528\u6237\u540d\r\n dm.KeyPressStr('username')\r\n dm.KeyPress(VirtualKeys.TAB)\r\n\r\n # \u8f93\u5165\u5bc6\u7801\r\n dm.KeyPressStr('password')\r\n dm.KeyPress(VirtualKeys.ENTER)\r\n\r\n # \u7b49\u5f85\u767b\u5f55\u5b8c\u6210\uff08\u627e\u56fe\u786e\u8ba4\uff09\r\n sleep(2)\r\n if dm.\u7b80\u6613\u627e\u56fe(0, 0, 800, 600, 'login_success.bmp'):\r\n print(\"\u767b\u5f55\u6210\u529f\uff01\")\r\n\r\n finally:\r\n # \u89e3\u7ed1\u7a97\u53e3\r\n dm.\u89e3\u7ed1\u7a97\u53e3()\r\n print(\"\u7a97\u53e3\u5df2\u89e3\u7ed1\")\r\n\r\nif __name__ == '__main__':\r\n main()\r\n```\r\n\r\n## \u8d21\u732e\r\n\r\n\u6b22\u8fce\u8d21\u732e\u4ee3\u7801\u6216\u63d0\u51fa\u5efa\u8bae\uff01\u8bf7\u53c2\u8003 [\u8d21\u732e\u6307\u5357](CONTRIBUTING.md) \u83b7\u53d6\u66f4\u591a\u4fe1\u606f\u3002\r\n\r\n## \u8bb8\u53ef\u8bc1\r\n\r\n\u672c\u9879\u76ee\u9075\u5faa [MIT \u8bb8\u53ef\u8bc1](LICENSE)\u3002\r\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "\u57fa\u4e8e\u5927\u6f20\u63d2\u4ef6\u7684Python\u81ea\u52a8\u5316\u5c01\u88c5\u5e93",
"version": "0.2.0",
"project_urls": {
"Homepage": "https://github.com/sandorn/xtdamo",
"Issues": "https://github.com/sandorn/xtdamo/issues",
"Repository": "https://github.com/sandorn/xtdamo"
},
"split_keywords": [
"automation",
" dm-plugin",
" mouse",
" keyboard",
" image-recognition"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "56c1c6cc7ddb80dc6b9a008f5281b21f29cbea5514b37126f75d725a1c0c5795",
"md5": "fc73c58e0a40dcf10f909deaa7ffcd74",
"sha256": "d6d1c2fb6bb1a3dbb4eb8da09d6d1fddab67d094ae5bcabca6dea7afdbff4639"
},
"downloads": -1,
"filename": "xtdamo-0.2.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "fc73c58e0a40dcf10f909deaa7ffcd74",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 56135,
"upload_time": "2025-10-25T08:28:39",
"upload_time_iso_8601": "2025-10-25T08:28:39.501050Z",
"url": "https://files.pythonhosted.org/packages/56/c1/c6cc7ddb80dc6b9a008f5281b21f29cbea5514b37126f75d725a1c0c5795/xtdamo-0.2.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "b56e1205187ea3cb88a9e02b16959b143e709bd885f559addcf7fcb5318cb440",
"md5": "01912da27f1577a95187ad7c4fc4a491",
"sha256": "5da47f492bcd7428ed72b467ca25e4f491e40faf55eead598935df8a7174707c"
},
"downloads": -1,
"filename": "xtdamo-0.2.0.tar.gz",
"has_sig": false,
"md5_digest": "01912da27f1577a95187ad7c4fc4a491",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 52991,
"upload_time": "2025-10-25T08:28:41",
"upload_time_iso_8601": "2025-10-25T08:28:41.422123Z",
"url": "https://files.pythonhosted.org/packages/b5/6e/1205187ea3cb88a9e02b16959b143e709bd885f559addcf7fcb5318cb440/xtdamo-0.2.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-25 08:28:41",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "sandorn",
"github_project": "xtdamo",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "xtdamo"
}