# DreamWall Picker - 窗口管理说明 ## ✅ 窗口管理机制 DreamWall Picker 已经实现了完善的单例模式和窗口管理机制,**无需额外修改**。 ### 核心机制 ```python # 全局单例实例 _dwpicker = None def show(): global _dwpicker if not _dwpicker: # 第一次调用:创建新实例 _dwpicker = DwPicker(...) # 已存在实例:直接显示 _dwpicker.show(dockable=True) ``` ### 特性 1. **单例模式** - 使用全局变量 `_dwpicker` 存储唯一实例 - 多次调用 `show()` 不会创建多个窗口 2. **智能显示** - 如果窗口已存在,直接显示 - 如果窗口被关闭,重新创建 3. **错误恢复** - 捕获 `RuntimeError`(workspace control 已存在) - 自动清理并重新显示 4. **正确清理** - `close()` 函数注销所有回调 - 清理实例引用 ## 📝 使用方法 ### 基本用法 ```python # 在 Maya Script Editor 中运行 import animation_tools.dwpicker animation_tools.dwpicker.show() ``` ### 多次调用(安全) ```python import animation_tools.dwpicker as dwpicker # 第一次调用 - 创建窗口 dwpicker.show() # 第二次调用 - 显示已存在的窗口(不会创建新的) dwpicker.show() # 第三次调用 - 仍然是同一个窗口 dwpicker.show() ``` ### 切换可见性 ```python import animation_tools.dwpicker as dwpicker # 切换窗口显示/隐藏 dwpicker.toggle() ``` ### 关闭窗口 ```python import animation_tools.dwpicker as dwpicker # 正确关闭窗口(清理所有回调) dwpicker.close() ``` ## 🎯 API 参考 ### `show(editable=True, pickers=None, ignore_scene_pickers=False, ...)` 显示 DreamWall Picker 窗口 **参数:** - `editable` (bool): 是否允许编辑(默认 True) - `pickers` (list[str]): 要打开的 picker 文件路径列表 - `ignore_scene_pickers` (bool): 是否忽略场景中的 pickers - `replace_namespace_function` (callable): 自定义命名空间替换函数 - `list_namespaces_function` (callable): 自定义命名空间列表函数 **返回:** - `DwPicker`: 窗口实例 **示例:** ```python import animation_tools.dwpicker as dwpicker # 默认模式 window = dwpicker.show() # 只读模式 window = dwpicker.show(editable=False) # 打开特定 picker 文件 window = dwpicker.show(pickers=['/path/to/picker.json']) # 忽略场景中的 pickers window = dwpicker.show(ignore_scene_pickers=True) ``` ### `toggle()` 切换窗口显示/隐藏 **示例:** ```python import animation_tools.dwpicker as dwpicker # 切换可见性 dwpicker.toggle() ``` ### `close()` 正确关闭窗口并清理资源 **示例:** ```python import animation_tools.dwpicker as dwpicker # 关闭窗口 dwpicker.close() ``` ### `current()` 获取当前显示的 picker widget **返回:** - Picker widget 或 None **示例:** ```python import animation_tools.dwpicker as dwpicker picker = dwpicker.current() if picker: print("Current picker:", picker) ``` ### `open_picker_file(filepath)` 程序化添加 picker 文件 **参数:** - `filepath` (str): picker 文件路径 **示例:** ```python import animation_tools.dwpicker as dwpicker dwpicker.open_picker_file('/path/to/picker.json') ``` ### `current_namespace()` 获取当前 picker 的命名空间 **返回:** - str: 命名空间 **示例:** ```python import animation_tools.dwpicker as dwpicker namespace = dwpicker.current_namespace() print("Current namespace:", namespace) ``` ## 🔧 高级功能 ### 上下文管理器 - 禁用回调 ```python import animation_tools.dwpicker as dwpicker # 临时禁用 picker 回调(提高性能) with dwpicker.disable(): # 执行大量选择操作 for obj in objects: cmds.select(obj, add=True) # 回调自动恢复 ``` ### 图层可见性控制 ```python import animation_tools.dwpicker as dwpicker # 设置图层可见性 dwpicker.set_layer_visible('layer_name', visible=True) # 切换图层可见性 dwpicker.toggle_layer_visibility('layer_name') ``` ### 获取形状 ```python import animation_tools.dwpicker as dwpicker # 通过 ID 获取形状 shape = dwpicker.get_shape('shape_id') ``` ## ✅ 与 MGPicker 的对比 | 特性 | DreamWall Picker | MGPicker | |------|-----------------|----------| | 单例模式 | ✅ 内置 | ✅ 已添加 | | 窗口检测 | ✅ 自动 | ✅ 已添加 | | 错误恢复 | ✅ 自动 | ⚠️ 手动 | | 回调管理 | ✅ 完善 | N/A | | 上下文管理器 | ✅ 支持 | N/A | ## 🎯 最佳实践 ### 1. 标准启动 ```python import animation_tools.dwpicker as dwpicker dwpicker.show() ``` ### 2. 工具架按钮 ```python # 简单切换 import animation_tools.dwpicker as dwpicker dwpicker.toggle() ``` ### 3. 批量操作时禁用回调 ```python import animation_tools.dwpicker as dwpicker with dwpicker.disable(): # 批量操作 for obj in objects: cmds.select(obj, add=True) ``` ### 4. 程序化加载 pickers ```python import animation_tools.dwpicker as dwpicker # 打开窗口 dwpicker.show() # 加载 picker 文件 dwpicker.open_picker_file('/path/to/picker.json') ``` ## ✨ 总结 DreamWall Picker 的窗口管理机制已经非常完善: - ✅ **单例模式** - 防止重复创建窗口 - ✅ **智能显示** - 自动处理已存在的窗口 - ✅ **错误恢复** - 自动处理 workspace control 冲突 - ✅ **正确清理** - 完善的资源管理 - ✅ **丰富 API** - 提供多种控制方法 **无需任何修改,可以直接使用!** ```python import animation_tools.dwpicker animation_tools.dwpicker.show() ``` 多次调用不会出现任何问题或警告!