219 lines
8.2 KiB
Python
219 lines
8.2 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 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()
|