Files
MetaFusion/scripts/Main.py
2025-05-05 19:57:27 +08:00

219 lines
8.2 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模块加载子模块显示
作者: CGNICO
版本: 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 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
#=========================================== 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
#======================================= 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(1200, 800)
self.setStyleSheet("")
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
# 设置窗口图标
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.main_tab_widget = QtWidgets.QTabWidget()
self.main_tab_widget.setObjectName("mainTabWidget")
# 创建各个标签页
self.toolbar_tab = QtWidgets.QWidget()
self.definition_tab = QtWidgets.QWidget()
self.geometry_tab = QtWidgets.QWidget()
self.rigging_tab = QtWidgets.QWidget()
self.behaviour_tab = QtWidgets.QWidget()
# 设置标签页名称
self.main_tab_widget.addTab(self.toolbar_tab, LANG.get("toolbar", "工具栏"))
self.main_tab_widget.addTab(self.definition_tab, LANG.get("definition", "定义"))
self.main_tab_widget.addTab(self.geometry_tab, LANG.get("geometry", "几何体"))
self.main_tab_widget.addTab(self.rigging_tab, LANG.get("rigging", "绑定"))
self.main_tab_widget.addTab(self.behaviour_tab, LANG.get("behaviour", "行为"))
#========================================= LAYOUT =======================================
def create_layouts(self):
"""创建布局"""
# 主布局
main_layout = QtWidgets.QVBoxLayout(self)
main_layout.setContentsMargins(5, 5, 5, 5)
main_layout.setSpacing(5)
main_layout.addWidget(self.main_tab_widget)
# 设置各标签页的布局
toolbar_layout = QtWidgets.QVBoxLayout(self.toolbar_tab)
definition_layout = QtWidgets.QVBoxLayout(self.definition_tab)
geometry_layout = QtWidgets.QVBoxLayout(self.geometry_tab)
rigging_layout = QtWidgets.QVBoxLayout(self.rigging_tab)
behaviour_layout = QtWidgets.QVBoxLayout(self.behaviour_tab)
# 将各UI模块添加到对应的标签页布局中
# 工具栏UI
if hasattr(self.toolbar_ui, 'main_widget'):
toolbar_layout.addWidget(self.toolbar_ui.main_widget)
# 定义UI
if hasattr(self.definition_ui, 'main_widget'):
definition_layout.addWidget(self.definition_ui.main_widget)
# 几何体UI
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)
#======================================= CONNECTION =====================================
def create_connections(self):
"""连接信号和槽"""
# 标签页切换信号
self.main_tab_widget.currentChanged.connect(self.tab_changed)
def tab_changed(self, index):
"""标签页切换事件处理"""
tab_name = self.main_tab_widget.tabText(index)
print(f"切换到标签页: {tab_name}")
# 调整分割器宽度
self.reset_splitters()
def reset_splitters(self):
"""重置所有分割器的宽度,确保左右栏宽度均等"""
# 延迟执行确保UI完全加载
QtCore.QTimer.singleShot(50, self._do_reset_splitters)
QtCore.QTimer.singleShot(200, self._do_reset_splitters)
def _do_reset_splitters(self):
"""实际执行分割器宽度重置的函数"""
current_tab = self.main_tab_widget.currentWidget()
if not current_tab:
return
# 查找当前标签页中的所有水平分割器
splitters = current_tab.findChildren(QtWidgets.QSplitter)
for splitter in splitters:
if splitter.orientation() == QtCore.Qt.Horizontal:
# 获取分割器宽度
width = splitter.width()
# 计算每个部分应该的宽度
count = splitter.count()
if count > 0:
part_width = width // count
sizes = [part_width] * count
# 设置分割器各部分的宽度
splitter.setSizes(sizes)
# 为每个子项设置相同的伸缩因子
for i in range(count):
splitter.setStretchFactor(i, 1)
def main():
"""主函数,创建并显示主窗口"""
try:
# 如果已存在窗口,则关闭
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()