#!/usr/bin/env python # -*- coding: utf-8 -*- """ Tool - Module Reload Tool Provides module reloading functionality for the plugin, supporting hot updates """ import sys import importlib import os import traceback from maya import cmds def get_all_py_files(start_path): """ Recursively get all .py files in the specified directory Returns: A list containing the paths of all .py files """ py_files = [] for root, dirs, files in os.walk(start_path): # Skip __pycache__ directory if '__pycache__' in dirs: dirs.remove('__pycache__') # Skip .git directory if '.git' in dirs: dirs.remove('.git') for file in files: if file.endswith('.py') and not file.startswith('__'): full_path = os.path.join(root, file) # Convert to module path format rel_path = os.path.relpath(full_path, start_path) module_path = os.path.splitext(rel_path)[0].replace(os.sep, '.') # Ensure module path format is correct if module_path.startswith("scripts."): module_path = module_path[8:] elif module_path.startswith("Scripts."): module_path = module_path[8:] py_files.append(module_path) return py_files def reload_Tool(): """ Reload Tool and all its related modules """ try: # Close existing Tool window if cmds.workspaceControl("ToolWorkspaceControl", exists=True): cmds.deleteUI("ToolWorkspaceControl", control=True) # Get scripts root directory SCRIPTS_PATH = os.path.dirname(os.path.dirname(__file__)) print(f"Reloading modules, path: {SCRIPTS_PATH}") # List of priority modules to reload priority_modules = [ "QtCompat", # First reload Qt compatibility module "config", # Then reload configuration module "utils", # Then reload utility modules "ui" # Finally reload UI modules ] # Get module paths for all .py files modules_to_reload = get_all_py_files(SCRIPTS_PATH) # Sort by module hierarchy, ensuring lower-level modules are reloaded first # First sort by priority, then by module hierarchy def module_sort_key(module_name): # Check if module is in priority list for i, prefix in enumerate(priority_modules): if module_name == prefix or module_name.startswith(prefix + "."): return (i, len(module_name.split('.'))) return (len(priority_modules), len(module_name.split('.'))) modules_to_reload.sort(key=module_sort_key) print("Module reload order:") for i, module in enumerate(modules_to_reload): print(f"{i+1}. {module}") print("\nStarting module reload...") # Reload all modules reloaded_modules = set() for module_name in modules_to_reload: try: if module_name in sys.modules: module = sys.modules[module_name] # Save reference to original module object for recovery if reload fails old_module = module try: importlib.reload(module) reloaded_modules.add(module_name) print(f"Module reloaded: {module_name}") except Exception as e: # Reload failed, restore original module sys.modules[module_name] = old_module print(f"Failed to reload module {module_name}: {str(e)}") traceback.print_exc() else: try: # Try to import unloaded module __import__(module_name) print(f"Module imported: {module_name}") except Exception as e: print(f"Failed to import module {module_name}: {str(e)}") except Exception as e: print(f"Error processing module {module_name}: {str(e)}") traceback.print_exc() print(f"\nSuccessfully reloaded {len(reloaded_modules)} modules") # Reimport main module try: import Main importlib.reload(Main) # Show UI Main.main() print("Tool reloaded successfully!") except Exception as e: print(f"Error reloading main module: {str(e)}") traceback.print_exc() # Reload complete except Exception as e: error_msg = f"Error reloading Tool: {str(e)}" print(error_msg) cmds.warning(error_msg) traceback.print_exc() def reload_all(): """ Execute reload and print separator lines """ print("\n" + "="*50) print("Starting reload of Tool and all its modules") print("="*50 + "\n") reload_Tool() print("\n" + "="*50) print("Reload complete") def reload_qt(): """ Reload Qt compatibility module """ try: # Reload QtCompat module if "QtCompat" in sys.modules: module = sys.modules["QtCompat"] importlib.reload(module) print("QtCompat module reloaded") # Reinitialize Qt module if hasattr(module, "init_qt"): qt_version = module.init_qt() print(f"Qt module reinitialized: {qt_version}") return True else: try: import QtCompat print("QtCompat module imported") return True except Exception as e: print(f"Import QtCompat module failed: {str(e)}") return False except Exception as e: print(f"Reload Qt module failed: {str(e)}") traceback.print_exc() return False # For backward compatibility, keep the original function name def reload_Tool(): """ Function kept for backward compatibility """ return reload_Tool() print("="*50 + "\n") # Execute reload # if __name__ == "__main__": # reload_all()