Files
MetaFusion/scripts/Main.py
2025-05-03 17:28:33 +08:00

284 lines
12 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Main module for Metahuman customize plugin
主模块 - 负责初始化UI和功能集成
功能: 从ui模块加载子模块显示
作者: Virtuos Games
版本: Alpha v1.0.0
"""
#===================================== IMPORT MODULES =====================================
from Qt import QtWidgets, QtCore, QtGui
from Qt.QtCompat import wrapInstance
from maya import OpenMayaUI as omui
import maya.cmds as cmds
import maya.mel as mel
import maya.utils as utils
import webbrowser
import subprocess
import importlib
import traceback
import locale
import sys
import os
#===================================== IMPORT UI MODULES ===================================
from scripts.ui import toolbar
from scripts.ui import geometry
from scripts.ui import rigging
from scripts.ui import behaviour
from scripts.ui import definition
#====================================== LOCALIZATION ==================================
from scripts.ui import localization
LANG = localization.LANG
#========================================== CONFIG ========================================
# 从 scripts 模块导入配置变量
from scripts import (
TOOL_NAME, TOOL_VERSION, TOOL_AUTHOR, TOOL_YEAR, TOOL_MOD_FILENAME,
TOOL_LANG, TOOL_WSCL_NAME, TOOL_HELP_URL, TOOL_PATH, SCRIPTS_PATH,
TOOL_MAIN_SCRIPT, UI_PATH, STYLE_FILE, ICONS_PATH, TOOL_ICON,
ASSETS_PATH, DNA_FILE_PATH, DNA_IMG_PATH, TOOL_COMMAND_ICON
)
#========================================= INIT =======================================
def get_system_encoding():
encoding = sys.getdefaultencoding()
if encoding.lower() == 'ascii':
encoding = locale.getpreferredencoding()
return encoding
def maya_main_window():
main_window_ptr = omui.MQtUtil.mainWindow()
return wrapInstance(int(main_window_ptr), QtWidgets.QWidget)
#===================================== MAIN FUNCTION ===================================
class MainWindow(QtWidgets.QWidget):
def __init__(self, parent=maya_main_window()):
super(MainWindow, self).__init__(parent)
self.setWindowTitle(TOOL_NAME)
self.setObjectName(f"{TOOL_NAME}MainWindow")
self.setWindowFlags(QtCore.Qt.Window)
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
# 设置自适应大小策略
self.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
self.setMinimumSize(300, 600) # 减小最小高度,让窗口更灵活
self.create_widgets()
self.create_layouts()
self.create_connections()
# 不设置窗口图标
def dock_to_maya(self):
if cmds.workspaceControl(TOOL_WSCL_NAME, exists=True):
cmds.deleteUI(TOOL_WSCL_NAME)
def create_control():
try:
# 直接使用TOOL_ICON__init__.py中已经检查了图标文件是否存在
workspace_control = cmds.workspaceControl(
TOOL_WSCL_NAME,
label=TOOL_NAME,
floating=True,
retain=True,
resizeWidth=True,
initialWidth=600,
minimumWidth=600
)
cmds.workspaceControl(TOOL_WSCL_NAME, e=True, resizeWidth=True)
cmds.control(self.objectName(), e=True, p=workspace_control)
# 尝试设置工作区控件的尺寸和属性
try:
# 使用Maya命令设置工作区控件属性
cmds.workspaceControl(TOOL_WSCL_NAME, e=True, widthProperty="preferred", heightProperty="preferred")
# 使用原始标题,不添加额外的图标字符
cmds.workspaceControl(TOOL_WSCL_NAME, e=True, label=TOOL_NAME)
except Exception as e:
print(f"设置工作区控件属性失败: {e}")
cmds.evalDeferred(lambda: cmds.workspaceControl(TOOL_WSCL_NAME, e=True, resizeWidth=True))
except Exception as e:
print("Error creating workspace control: {}".format(e))
cmds.evalDeferred(create_control)
#===================================== UI COMPONENTS =====================================
def create_widgets(self):
# 创建滚动区域
self.scroll_area = QtWidgets.QScrollArea()
self.scroll_area.setObjectName("main_scroll_area")
self.scroll_area.setWidgetResizable(True)
self.scroll_area.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.scroll_area.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded) # 改回按需显示
self.scroll_area.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
# 创建滚动区域内容控件
self.scroll_content = QtWidgets.QWidget()
self.scroll_content.setObjectName("scroll_content")
self.scroll_content.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
# 创建主标签页
self.main_tab = QtWidgets.QTabWidget()
self.main_tab.setObjectName("main_tab")
self.main_tab.setTabPosition(QtWidgets.QTabWidget.North)
self.main_tab.setTabShape(QtWidgets.QTabWidget.Rounded)
self.main_tab.setDocumentMode(True)
self.main_tab.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
self.main_tab.setMinimumHeight(400)
# 创建各功能模块标签页
self.geometry_tab = QtWidgets.QWidget()
self.geometry_tab.setObjectName("geometry_tab")
self.geometry_tab.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
self.rigging_tab = QtWidgets.QWidget()
self.rigging_tab.setObjectName("rigging_tab")
self.rigging_tab.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
self.behaviour_tab = QtWidgets.QWidget()
self.behaviour_tab.setObjectName("behaviour_tab")
self.behaviour_tab.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
self.definition_tab = QtWidgets.QWidget()
self.definition_tab.setObjectName("definition_tab")
self.definition_tab.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
# 创建工具栏
self.toolbar_frame = QtWidgets.QFrame()
self.toolbar_frame.setObjectName("toolbar_frame")
self.toolbar_frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.toolbar_frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.toolbar_frame.setMaximumHeight(40)
self.toolbar_frame.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
# 创建状态栏
self.status_bar = QtWidgets.QStatusBar()
self.status_bar.setObjectName("status_bar")
self.status_bar.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
self.status_bar.showMessage(f"{TOOL_NAME} {TOOL_VERSION}")
# 初始化各模块UI组件
toolbar.widgets()
geometry.widgets()
rigging.widgets()
behaviour.widgets()
definition.widgets()
def create_layouts(self):
# 主布局
self.main_layout = QtWidgets.QVBoxLayout(self)
self.main_layout.setContentsMargins(2, 2, 2, 2)
self.main_layout.setSpacing(2)
# 滚动区域内容布局
self.scroll_content_layout = QtWidgets.QVBoxLayout(self.scroll_content)
self.scroll_content_layout.setContentsMargins(2, 2, 2, 2)
self.scroll_content_layout.setSpacing(2)
# 创建工具栏布局
self.toolbar_layout = QtWidgets.QVBoxLayout(self.toolbar_frame)
self.toolbar_layout.setContentsMargins(0, 0, 0, 0)
# 使用toolbar模块创建工具栏元素
toolbar.layouts(parent_frame=self.toolbar_frame)
# 设置各标签页布局
self.geometry_layout = QtWidgets.QVBoxLayout(self.geometry_tab)
self.geometry_layout.setContentsMargins(4, 4, 4, 4)
geometry.layouts(parent_tab=self.geometry_tab)
self.rigging_layout = QtWidgets.QVBoxLayout(self.rigging_tab)
self.rigging_layout.setContentsMargins(4, 4, 4, 4)
rigging.layouts(parent_tab=self.rigging_tab)
self.behaviour_layout = QtWidgets.QVBoxLayout(self.behaviour_tab)
self.behaviour_layout.setContentsMargins(4, 4, 4, 4)
behaviour.layouts(parent_tab=self.behaviour_tab)
self.definition_layout = QtWidgets.QVBoxLayout(self.definition_tab)
self.definition_layout.setContentsMargins(4, 4, 4, 4)
definition.layouts(parent_tab=self.definition_tab)
# 添加标签页到主标签控件
self.main_tab.addTab(self.geometry_tab, "几何模型")
self.main_tab.addTab(self.rigging_tab, "绑定系统")
self.main_tab.addTab(self.behaviour_tab, "行为系统")
self.main_tab.addTab(self.definition_tab, "定义系统")
# 将组件添加到滚动区域内容布局
self.scroll_content_layout.addWidget(self.toolbar_frame)
self.scroll_content_layout.addWidget(self.main_tab)
# 设置滚动区域的内容控件
self.scroll_area.setWidget(self.scroll_content)
# 将滚动区域和状态栏添加到主布局
self.main_layout.addWidget(self.scroll_area)
self.main_layout.addWidget(self.status_bar)
# 加载样式表
if os.path.exists(STYLE_FILE):
try:
with open(STYLE_FILE, "r", encoding="utf-8") as f:
style = f.read()
self.setStyleSheet(style)
except UnicodeDecodeError:
# 尝试使用系统默认编码
encoding = get_system_encoding()
try:
with open(STYLE_FILE, "r", encoding=encoding) as f:
style = f.read()
self.setStyleSheet(style)
except Exception as e:
print(f"警告: 无法加载样式表文件: {e}")
else:
print(f"警告: 样式表文件不存在: {STYLE_FILE}")
def create_connections(self):
# 连接各模块的信号和槽
toolbar.connections()
geometry.connections()
rigging.connections()
behaviour.connections()
definition.connections()
# 标签页切换信号
self.main_tab.currentChanged.connect(self.on_tab_changed)
def on_tab_changed(self, index):
tab_name = self.main_tab.tabText(index)
self.status_bar.showMessage(f"当前模块: {tab_name}")
print(f"切换到模块: {tab_name}")
def main():
"""
Main function to initialize and show the Plugin UI
"""
try:
# Initialize UI modules with placeholder functions
# Each module only contains UI framework without actual functionality
toolbar.toolbar_temp_function()
geometry.geometry_temp_function()
rigging.rigging_temp_function()
behaviour.behaviour_temp_function()
definition.definition_temp_function()
# Create and show main window
global tool_window
tool_window = MainWindow()
tool_window.dock_to_maya()
print(f"{TOOL_NAME} plugin initialized successfully!")
return tool_window
except Exception as e:
error_msg = f"Error initializing {TOOL_NAME} plugin: {str(e)}"
print(error_msg)
traceback.print_exc()
cmds.warning(error_msg)
return None
# Auto-run when imported
if __name__ == "__main__":
main()