Files
MetaFusion/scripts/Main.py
2025-05-08 00:39:41 +08:00

258 lines
10 KiB
Python

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Main module for Metahuman customize plugin
主模块 - 负责初始化UI和功能集成
功能: 从ui模块加载子模块显示
作者: CGNICO
版本: Alpha v1.0.0
"""
#===================================== IMPORT MODULES =====================================
from ui.Qt import QtWidgets, QtCore, QtGui
from ui.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 ui_utils
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
get_text = localization.get_text
#=========================================== CONFIG =========================================
import config
TOOL_NAME = config.TOOL_NAME
TOOL_VERSION = config.TOOL_VERSION
TOOL_AUTHOR = config.TOOL_AUTHOR
TOOL_YEAR = config.TOOL_YEAR
TOOL_MOD_FILENAME = config.TOOL_MOD_FILENAME
TOOL_LANG = config.TOOL_LANG
TOOL_WSCL_NAME = config.TOOL_WSCL_NAME
TOOL_HELP_URL = config.TOOL_HELP_URL
TOOL_PATH = config.TOOL_PATH
SCRIPTS_PATH = config.SCRIPTS_PATH
TOOL_MAIN_SCRIPT = config.TOOL_MAIN_SCRIPT
UI_PATH = config.UI_PATH
STYLE_FILE = config.STYLE_FILE
ICONS_PATH = config.ICONS_PATH
TOOL_ICON = config.TOOL_ICON
ASSETS_PATH = config.ASSETS_PATH
DNA_FILE_PATH = config.DNA_FILE_PATH
DNA_IMG_PATH = config.DNA_IMG_PATH
TOOL_COMMAND_ICON = config.TOOL_COMMAND_ICON
TOOL_WIDTH = config.TOOL_WIDTH
TOOL_HEIGHT = config.TOOL_HEIGHT
#======================================= MAIN FUNCTION =====================================
class MainWindow(QtWidgets.QWidget):
def __init__(self, parent=ui_utils.get_maya_main_window()):
super(MainWindow, self).__init__(parent)
self.setWindowTitle(TOOL_NAME)
self.setObjectName(f"{TOOL_NAME}MainWindow")
self.setMinimumSize(TOOL_WIDTH, TOOL_HEIGHT)
self.setStyleSheet("")
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
# 设置窗口为独立窗口
self.setWindowFlags(QtCore.Qt.Window)
# 设置窗口图标
if os.path.exists(TOOL_ICON):
self.setWindowIcon(QtGui.QIcon(TOOL_ICON))
# 加载样式表
self.load_stylesheet()
# 初始化UI模块
self.toolbar_ui = toolbar.ToolbarUI()
self.definition_ui = definition.DefinitionUI()
self.geometry_ui = geometry.GeometryUI()
self.rigging_ui = rigging.RiggingUI()
self.behaviour_ui = behaviour.BehaviourUI()
# 初始化UI组件
self.create_widgets()
self.create_layouts()
self.create_connections()
def load_stylesheet(self):
"""加载样式表"""
if os.path.exists(STYLE_FILE):
try:
with open(STYLE_FILE, 'r', encoding='utf-8') as f:
style = f.read()
self.setStyleSheet(style)
print(f"样式表已加载: {STYLE_FILE}")
except Exception as e:
print(f"加载样式表失败: {e}")
else:
print(f"样式表文件不存在: {STYLE_FILE}")
#========================================= WIDGET =======================================
def create_widgets(self):
"""创建UI控件"""
# 创建工具栏区域
self.toolbar_widget = QtWidgets.QWidget()
self.toolbar_widget.setObjectName("toolbarWidget")
self.toolbar_widget.setMaximumHeight(80)
# 创建功能区域切换按钮组
self.function_buttons = {}
self.function_buttons["geometry"] = QtWidgets.QPushButton(get_text("geometry", "几何体"))
self.function_buttons["geometry"].setIcon(ui_utils.load_icon("meshes.png"))
self.function_buttons["rigging"] = QtWidgets.QPushButton(get_text("rigging", "绑定"))
self.function_buttons["rigging"].setIcon(ui_utils.load_icon("configuration.png"))
self.function_buttons["behaviour"] = QtWidgets.QPushButton(get_text("behaviour", "行为"))
self.function_buttons["behaviour"].setIcon(ui_utils.load_icon("behaviour.png"))
self.function_buttons["definition"] = QtWidgets.QPushButton(get_text("definition", "定义"))
self.function_buttons["definition"].setIcon(ui_utils.load_icon("definition.png"))
# 设置按钮样式和属性
for key, button in self.function_buttons.items():
button.setObjectName(f"{key}Button")
button.setCheckable(True)
button.setMinimumHeight(40)
# 默认选中几何体按钮
self.function_buttons["geometry"].setChecked(True)
# 创建功能面板堆栈
self.function_stack = QtWidgets.QStackedWidget()
self.function_stack.setObjectName("functionStack")
# 创建各个功能面板
self.geometry_panel = QtWidgets.QWidget()
self.rigging_panel = QtWidgets.QWidget()
self.behaviour_panel = QtWidgets.QWidget()
self.definition_panel = QtWidgets.QWidget()
# 将功能面板添加到堆栈中
self.function_stack.addWidget(self.geometry_panel)
self.function_stack.addWidget(self.rigging_panel)
self.function_stack.addWidget(self.behaviour_panel)
self.function_stack.addWidget(self.definition_panel)
#========================================= LAYOUT =======================================
def create_layouts(self):
"""创建布局"""
# 主布局
main_layout = QtWidgets.QVBoxLayout(self)
main_layout.setContentsMargins(2, 2, 2, 2)
main_layout.setSpacing(2)
# 创建工具栏布局
toolbar_layout = QtWidgets.QHBoxLayout(self.toolbar_widget)
toolbar_layout.setContentsMargins(5, 5, 5, 5)
toolbar_layout.setSpacing(5)
# 将工具栏UI添加到工具栏布局
if hasattr(self.toolbar_ui, 'main_widget'):
toolbar_layout.addWidget(self.toolbar_ui.main_widget)
# 创建功能按钮布局
function_buttons_layout = QtWidgets.QHBoxLayout()
function_buttons_layout.setContentsMargins(0, 0, 0, 0)
function_buttons_layout.setSpacing(2)
# 添加功能按钮
for key, button in self.function_buttons.items():
function_buttons_layout.addWidget(button)
# 创建各功能面板的布局
definition_layout = QtWidgets.QVBoxLayout(self.definition_panel)
definition_layout.setContentsMargins(0, 0, 0, 0)
definition_layout.setSpacing(0)
geometry_layout = QtWidgets.QVBoxLayout(self.geometry_panel)
geometry_layout.setContentsMargins(0, 0, 0, 0)
geometry_layout.setSpacing(0)
rigging_layout = QtWidgets.QVBoxLayout(self.rigging_panel)
rigging_layout.setContentsMargins(0, 0, 0, 0)
rigging_layout.setSpacing(0)
behaviour_layout = QtWidgets.QVBoxLayout(self.behaviour_panel)
behaviour_layout.setContentsMargins(0, 0, 0, 0)
behaviour_layout.setSpacing(0)
# 将各UI模块添加到对应的功能面板布局中
if hasattr(self.definition_ui, 'main_widget'):
definition_layout.addWidget(self.definition_ui.main_widget)
if hasattr(self.geometry_ui, 'main_widget'):
geometry_layout.addWidget(self.geometry_ui.main_widget)
# 绑定UI
if hasattr(self.rigging_ui, 'main_widget'):
rigging_layout.addWidget(self.rigging_ui.main_widget)
# 行为UI
if hasattr(self.behaviour_ui, 'main_widget'):
behaviour_layout.addWidget(self.behaviour_ui.main_widget)
# 将各组件添加到主布局
main_layout.addWidget(self.toolbar_widget)
main_layout.addLayout(function_buttons_layout)
main_layout.addWidget(self.function_stack, 1) # 给功能面板堆栈设置伸缩因子,使其占据剩余空间
#======================================= CONNECTION =====================================
def create_connections(self):
"""连接信号和槽"""
# 功能按钮点击信号
self.function_buttons["geometry"].clicked.connect(lambda: self.switch_function_panel(0))
self.function_buttons["rigging"].clicked.connect(lambda: self.switch_function_panel(1))
self.function_buttons["behaviour"].clicked.connect(lambda: self.switch_function_panel(2))
self.function_buttons["definition"].clicked.connect(lambda: self.switch_function_panel(3))
def switch_function_panel(self, index):
"""切换功能面板"""
# 切换堆栈页面
self.function_stack.setCurrentIndex(index)
# 更新按钮状态
for i, (key, button) in enumerate(self.function_buttons.items()):
button.setChecked(i == index)
# 打印当前面板信息
panel_names = ["几何体", "绑定", "行为", "定义"]
print(f"切换到功能面板: {panel_names[index]}")
def main():
"""主函数,创建并显示主窗口"""
try:
# 应用当前语言设置
from scripts.ui import localization
config.TOOL_LANG = localization.get_current_language()
# 如果已存在窗口,则关闭
for widget in QtWidgets.QApplication.allWidgets():
if widget.objectName() == f"{TOOL_NAME}MainWindow" and isinstance(widget, QtWidgets.QWidget):
widget.close()
widget.deleteLater()
# 创建新窗口
window = MainWindow()
window.show()
return window
except Exception as e:
error_msg = traceback.format_exc()
print(f"启动失败: {e}\n{error_msg}")
return None
if __name__ == "__main__":
main()