diff --git a/.windsurfrules b/.windsurfrules
index b14416e..e82e039 100644
--- a/.windsurfrules
+++ b/.windsurfrules
@@ -166,7 +166,7 @@ We support one-click to correct the pose of the character to the correct pose, a
- Face and panel controllers can be seamlessly switched, use context7;
- https://pointart.oss-cn-hangzhou.aliyuncs.com/wp-content/uploads/2024/06/%E9%9D%A2%E9%83%A8%E6%8E%A7%E5%88%B6%E5%99%A8.mp4, use context7;
-- Aiming at the problem that Metahuman's face control panel is not intuitive, we support the generation of a brand-new face controller, which can directly adjust the expression and muscles of the character on the face. If you contact Metahuman controller soon, it will greatly reduce your learning cost.
+- Aiming at the problem that Metahuman face control panel is not intuitive, we support the generation of a brand-new face controller, which can directly adjust the expression and muscles of the character on the face. If you contact Metahuman controller soon, it will greatly reduce your learning cost.
#### 1.1.7. Different topological binding
diff --git a/Plan.md b/Plan.md
index 05daca3..e46c459 100644
--- a/Plan.md
+++ b/Plan.md
@@ -154,13 +154,30 @@ MetaHumanDNAPlugin/
## 进度记录与后续安排
-### 2025-05-06 更新
+### 2025-05-08 更新
-- 基础框架与UI阶段(第一阶段)已完成95%
-- 完成了主要UI模块的创建和基本功能实现
+#### 已完成
+- 基础框架与UI(第一阶段)已完成95%
+- 主界面与四大核心面板(geometry/rigging/behaviour/definition)功能与布局基本完善
+- 行为面板(behaviour.py)布局结构已规范化,分割器与面板嵌套逻辑已修正,交互体验提升
+- 多语言映射文件(localization.py)已补全,支持各主要功能区和按钮的中英文切换
- 优化了项目结构,明确了各模块的职责和接口
-- 需要进行UI微调与优化,包括统一样式、完善交互等
-- DNA处理核心模块已初步实现,需要进一步完善与测试
+- 参考Epic官方MetaHuman DNA Calibration与SuperRigging等插件,吸收最佳实践
+
+#### 进行中
+- UI微调与优化(统一按钮样式、图标、响应式布局)
+- 多语言支持完善(持续补全各模块UI文本映射)
+- DNA核心功能开发(dnalib模块完善、MetaHuman DNA标准兼容、文件导入导出)
+- 增强UI与Maya交互的稳定性,优化性能,减少重绘
+- 行为、定义、几何等面板的交互细节持续优化
+
+#### 下一步
+- 完成所有UI面板的多语言、样式、布局一致性
+- 完善DNA文件读写、MetaHuman兼容与一键式流程
+- 开发批量处理、自动化绑定与多LOD支持
+- 增强文档与测试,持续同步开发进度
+
+---
### 2025-04-30 更新
diff --git a/config.py b/config.py
index 3390ae5..54805ed 100644
--- a/config.py
+++ b/config.py
@@ -14,7 +14,7 @@ TOOL_YEAR = "2025"
TOOL_MOD_FILENAME = f"{TOOL_NAME.lower()}.mod"
TOOL_LANG = "en_US"
TOOL_WSCL_NAME = f"{TOOL_NAME}WorkspaceControl"
-TOOL_HELP_URL = f"http://10.72.61.59:3000/ArtGroup/{TOOL_NAME}/wiki"
+TOOL_HELP_URL = f"https://gitea.cgnico.com/CGNICO/{TOOL_NAME}/wiki"
# Path Configuration
TOOL_PATH = os.path.dirname(os.path.abspath(__file__)).replace("\\", "/")
diff --git a/scripts/Main.py b/scripts/Main.py
index b1ef12a..672dae1 100644
--- a/scripts/Main.py
+++ b/scripts/Main.py
@@ -31,8 +31,7 @@ from scripts.ui import behaviour
from scripts.ui import definition
#========================================= LOCALIZATION =====================================
from scripts.ui import localization
-LANG = localization.LANG
-get_text = localization.get_text
+TEXT = localization.TEXT
#=========================================== CONFIG =========================================
import config
TOOL_NAME = config.TOOL_NAME
@@ -111,13 +110,13 @@ class MainWindow(QtWidgets.QWidget):
# 创建功能区域切换按钮组
self.function_buttons = {}
- self.function_buttons["geometry"] = QtWidgets.QPushButton(get_text("geometry", "几何体"))
+ self.function_buttons["geometry"] = QtWidgets.QPushButton(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"] = QtWidgets.QPushButton(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"] = QtWidgets.QPushButton(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"] = QtWidgets.QPushButton(TEXT("definition", "定义"))
self.function_buttons["definition"].setIcon(ui_utils.load_icon("definition.png"))
# 设置按钮样式和属性
diff --git a/scripts/ReloadModules.py b/scripts/ReloadModules.py
index 6cab00d..e39df32 100644
--- a/scripts/ReloadModules.py
+++ b/scripts/ReloadModules.py
@@ -51,6 +51,9 @@ except ImportError:
HAS_QT = False
print("警告: 无法导入Qt模块,UI功能将不可用")
+import config
+TOOL_NAME = config.TOOL_NAME
+
#===================================== 公共函数 =====================================
def clean_pycache(root_dir):
"""
@@ -411,7 +414,7 @@ class ModuleReloaderUI(QtWidgets.QDialog):
parent = parent or getMayaMainWindow()
super(ModuleReloaderUI, self).__init__(parent)
- self.setWindowTitle(f"{TOOL_NAME} - 模块重载工具")
+ self.setWindowTitle("模块重载工具")
self.setMinimumWidth(600)
self.setMinimumHeight(500)
self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowStaysOnTopHint)
@@ -427,7 +430,7 @@ class ModuleReloaderUI(QtWidgets.QDialog):
main_layout.setSpacing(10)
# 标题标签
- title_label = QtWidgets.QLabel(f"{TOOL_NAME} 模块重载工具")
+ title_label = QtWidgets.QLabel("模块重载工具")
title_label.setStyleSheet("font-size: 16px; font-weight: bold;")
main_layout.addWidget(title_label)
diff --git a/scripts/ui/behaviour.py b/scripts/ui/behaviour.py
index d511a09..841c211 100644
--- a/scripts/ui/behaviour.py
+++ b/scripts/ui/behaviour.py
@@ -17,8 +17,8 @@ Behaviour UI Module for Plugin
- 控制面板查找
"""
#========================================= IMPORT =========================================
-from Qt import QtWidgets, QtCore, QtGui
-from Qt.QtCompat import wrapInstance
+from scripts.ui.Qt import QtWidgets, QtCore, QtGui
+from scripts.ui.Qt.QtCompat import wrapInstance
from maya import OpenMayaUI as omui
import maya.cmds as cmds
import maya.mel as mel
@@ -57,51 +57,29 @@ TOOL_WIDTH = config.TOOL_WIDTH
TOOL_HEIGHT = config.TOOL_HEIGHT
#========================================= LOCATION =======================================
from scripts.ui import localization
-LANG = localization.LANG
-get_text = localization.get_text
+TEXT = localization.TEXT
class BehaviourUI(ui_utils.BaseUI):
"""
行为系统UI类 - 负责显示角色行为编辑界面和基础操作
继承自BaseUI类,实现行为系统相关的UI功能
"""
- # 类变量,存储单例实例
- _instance = None
-
- @classmethod
- def get_instance(cls):
- """
- 获取BehaviourUI的单例实例
-
- Returns:
- BehaviourUI: 单例实例,如果不存在则返回None
- """
- return cls._instance
-
+ #========================================== INIT ========================================
def __init__(self, parent=None):
- """
- 初始化行为系统UI
- """
- super(BehaviourUI, self).__init__() # 不传递parent参数给BaseUI
-
- # 设置单例实例
- BehaviourUI._instance = self
+ super().__init__(parent)
# 创建主控件
- self.main_widget = QtWidgets.QWidget(parent)
+ self.main_widget = QtWidgets.QWidget()
self.main_widget.setObjectName("behaviourMainWidget")
- # 初始化控件、布局和按钮字典
- self.controls = {}
- self.layouts = {}
- self.buttons = {}
- self.splitters = {}
-
# 创建UI组件
self.create_widgets()
self.create_layouts()
self.create_connections()
+ # 更新UI文本
+ self.update_language()
+
# 设置全局样式,确保所有控件都没有最小宽度限制
self.main_widget.setStyleSheet("""
QWidget { min-width: 0px; }
@@ -118,7 +96,7 @@ class BehaviourUI(ui_utils.BaseUI):
包括标题标签、搜索框、控制列表、滑块等
"""
# 标题标签
- self.controls["title_label"] = QtWidgets.QLabel(get_text("behaviour_title", "行为系统"))
+ self.controls["title_label"] = QtWidgets.QLabel(TEXT("behaviour_title", "行为系统"))
self.controls["title_label"].setObjectName("behaviourTitleLabel")
self.controls["title_label"].setAlignment(QtCore.Qt.AlignCenter)
self.controls["title_label"].setStyleSheet("font-size: 14px; font-weight: bold; padding: 5px;")
@@ -141,7 +119,7 @@ class BehaviourUI(ui_utils.BaseUI):
# 搜索框
self.controls["search_input"] = QtWidgets.QLineEdit()
self.controls["search_input"].setObjectName("searchInput")
- self.controls["search_input"].setPlaceholderText(get_text("search", "搜索..."))
+ self.controls["search_input"].setPlaceholderText(TEXT("search", "搜索..."))
self.controls["search_input"].setFixedHeight(25)
# 控制列表
@@ -193,27 +171,27 @@ class BehaviourUI(ui_utils.BaseUI):
self.buttons["page_6"].setCheckable(True)
# 左下角Range按钮
- self.buttons["range_minus"] = QtWidgets.QPushButton(get_text(" Range - ", " 范围 - "))
+ self.buttons["range_minus"] = QtWidgets.QPushButton(TEXT(" Range - ", " 范围 - "))
self.buttons["range_minus"].setObjectName("rangeMinusButton")
self.buttons["range_minus"].setIcon(ui_utils.load_icon("behaviour.png"))
self.buttons["range_minus"].setMinimumWidth(0)
- self.buttons["range_plus"] = QtWidgets.QPushButton(get_text(" Range + ", " 范围 + "))
+ self.buttons["range_plus"] = QtWidgets.QPushButton(TEXT(" Range + ", " 范围 + "))
self.buttons["range_plus"].setObjectName("rangePlusButton")
self.buttons["range_plus"].setIcon(ui_utils.load_icon("behaviour.png"))
self.buttons["range_plus"].setMinimumWidth(0)
# 左侧面板控件 - Raw Control
- self.controls["raw_control_group"] = QtWidgets.QGroupBox(get_text("Raw Control", "原始控制"))
+ self.controls["raw_control_group"] = QtWidgets.QGroupBox(TEXT("Raw Control", "原始控制"))
self.controls["raw_control_group"].setObjectName("rawControlGroup")
- self.controls["raw_control_group"].setTitle(get_text("Raw Control", "原始控制"))
+ self.controls["raw_control_group"].setTitle(TEXT("Raw Control", "原始控制"))
self.controls["raw_control_group"].setFixedHeight(25)
# 右侧面板控件 - Related BlendShapes
- self.controls["blendshapes_group"] = QtWidgets.QGroupBox(get_text("Related BlendShapes", "相关BlendShapes"))
+ self.controls["blendshapes_group"] = QtWidgets.QGroupBox(TEXT("Related BlendShapes", "相关BlendShapes"))
self.controls["blendshapes_group"].setObjectName("blendshapesGroup")
- self.controls["blendshapes_group"].setTitle(get_text("Related BlendShapes", "相关BlendShapes"))
+ self.controls["blendshapes_group"].setTitle(TEXT("Related BlendShapes", "相关BlendShapes"))
self.controls["blendshapes_group"].setFixedHeight(25)
# BlendShapes列表
@@ -239,60 +217,60 @@ class BehaviourUI(ui_utils.BaseUI):
self.controls["bs_slider_all_check"].setObjectName("bsSliderAllCheck")
# 右下角BS Range按钮
- self.buttons["bs_range_minus"] = QtWidgets.QPushButton(get_text(" Range - ", " 范围 - "))
+ self.buttons["bs_range_minus"] = QtWidgets.QPushButton(TEXT(" Range - ", " 范围 - "))
self.buttons["bs_range_minus"].setObjectName("bsRangeMinusButton")
self.buttons["bs_range_minus"].setIcon(ui_utils.load_icon("behaviour.png"))
self.buttons["bs_range_minus"].setMinimumWidth(0)
- self.buttons["bs_range_plus"] = QtWidgets.QPushButton(get_text(" Range + ", " 范围 + "))
+ self.buttons["bs_range_plus"] = QtWidgets.QPushButton(TEXT(" Range + ", " 范围 + "))
self.buttons["bs_range_plus"].setObjectName("bsRangePlusButton")
self.buttons["bs_range_plus"].setIcon(ui_utils.load_icon("behaviour.png"))
self.buttons["bs_range_plus"].setMinimumWidth(0)
# BlendShape操作按钮
- self.buttons["flip_target"] = QtWidgets.QPushButton(get_text("Flip Target", "翻转目标"))
+ self.buttons["flip_target"] = QtWidgets.QPushButton(TEXT("Flip Target", "翻转目标"))
self.buttons["flip_target"].setObjectName("flipTargetButton")
self.buttons["flip_target"].setIcon(ui_utils.load_icon("mirrorL.png"))
- self.buttons["mirror_target"] = QtWidgets.QPushButton(get_text("Mirror Target", "镜像目标"))
+ self.buttons["mirror_target"] = QtWidgets.QPushButton(TEXT("Mirror Target", "镜像目标"))
self.buttons["mirror_target"].setObjectName("mirrorTargetButton")
self.buttons["mirror_target"].setIcon(ui_utils.load_icon("mirror.png"))
- self.buttons["find_flip_target"] = QtWidgets.QPushButton(get_text("Find Flip Target", "查找翻转目标"))
+ self.buttons["find_flip_target"] = QtWidgets.QPushButton(TEXT("Find Flip Target", "查找翻转目标"))
self.buttons["find_flip_target"].setObjectName("findFlipTargetButton")
self.buttons["find_flip_target"].setIcon(ui_utils.load_icon("mirrorR.png"))
- self.buttons["add_blendshape"] = QtWidgets.QPushButton(get_text("Add BlendShape", "添加BlendShape"))
+ self.buttons["add_blendshape"] = QtWidgets.QPushButton(TEXT("Add BlendShape", "添加BlendShape"))
self.buttons["add_blendshape"].setObjectName("addBlendshapeButton")
self.buttons["add_blendshape"].setIcon(ui_utils.load_icon("blendShape.png"))
- self.buttons["delete_blendshape"] = QtWidgets.QPushButton(get_text("Delete BlendShape", "删除BlendShape"))
+ self.buttons["delete_blendshape"] = QtWidgets.QPushButton(TEXT("Delete BlendShape", "删除BlendShape"))
self.buttons["delete_blendshape"].setObjectName("deleteBlendshapeButton")
self.buttons["delete_blendshape"].setIcon(ui_utils.load_icon("blendShape.png"))
- self.buttons["batch_blendshape"] = QtWidgets.QPushButton(get_text("Batch BlendShape", "批量BlendShape"))
+ self.buttons["batch_blendshape"] = QtWidgets.QPushButton(TEXT("Batch BlendShape", "批量BlendShape"))
self.buttons["batch_blendshape"].setObjectName("batchBlendshapeButton")
self.buttons["batch_blendshape"].setIcon(ui_utils.load_icon("blendShape.png"))
- self.buttons["bs_range_minus"] = QtWidgets.QPushButton(get_text(" Range - ", " 范围 - "))
+ self.buttons["bs_range_minus"] = QtWidgets.QPushButton(TEXT(" Range - ", " 范围 - "))
self.buttons["bs_range_minus"].setObjectName("bsRangeMinusButton")
self.buttons["bs_range_minus"].setIcon(ui_utils.load_icon("behaviour.png"))
self.buttons["bs_range_minus"].setMinimumWidth(0)
- self.buttons["bs_range_plus"] = QtWidgets.QPushButton(get_text(" Range + ", " 范围 + "))
+ self.buttons["bs_range_plus"] = QtWidgets.QPushButton(TEXT(" Range + ", " 范围 + "))
self.buttons["bs_range_plus"].setObjectName("bsRangePlusButton")
self.buttons["bs_range_plus"].setIcon(ui_utils.load_icon("behaviour.png"))
self.buttons["bs_range_plus"].setMinimumWidth(0)
- self.buttons["rebuild_select"] = QtWidgets.QPushButton(get_text("Rebuild Select", "重建选择"))
+ self.buttons["rebuild_select"] = QtWidgets.QPushButton(TEXT("Rebuild Select", "重建选择"))
self.buttons["rebuild_select"].setObjectName("rebuildSelectButton")
self.buttons["rebuild_select"].setIcon(ui_utils.load_icon("loading.png"))
- self.buttons["reposition_joints"] = QtWidgets.QPushButton(get_text("Reposition Joints", "重新定位关节"))
+ self.buttons["reposition_joints"] = QtWidgets.QPushButton(TEXT("Reposition Joints", "重新定位关节"))
self.buttons["reposition_joints"].setObjectName("repositionJointsButton")
self.buttons["reposition_joints"].setIcon(ui_utils.load_icon("loading.png"))
- self.buttons["blend_select"] = QtWidgets.QPushButton(get_text("Blend Select", "混合选择"))
+ self.buttons["blend_select"] = QtWidgets.QPushButton(TEXT("Blend Select", "混合选择"))
self.buttons["blend_select"].setObjectName("blendSelectButton")
self.buttons["blend_select"].setIcon(ui_utils.load_icon("loading.png"))
@@ -314,64 +292,64 @@ class BehaviourUI(ui_utils.BaseUI):
self.controls["bottom_slider_all_check"].setObjectName("bottomSliderAllCheck")
# 底部标签页按钮
- self.buttons["tab_psd"] = QtWidgets.QPushButton(get_text("PSD", "PSD"))
+ self.buttons["tab_psd"] = QtWidgets.QPushButton(TEXT("PSD", "PSD"))
self.buttons["tab_psd"].setIcon(ui_utils.load_icon("psd.png"))
self.buttons["tab_psd"].setObjectName("tabPsdButton")
self.buttons["tab_psd"].setCheckable(True)
self.buttons["tab_psd"].setChecked(True)
- self.buttons["tab_bse"] = QtWidgets.QPushButton(get_text("BSE", "BSE"))
+ self.buttons["tab_bse"] = QtWidgets.QPushButton(TEXT("BSE", "BSE"))
self.buttons["tab_bse"].setIcon(ui_utils.load_icon("blendShape.png"))
self.buttons["tab_bse"].setObjectName("tabBseButton")
self.buttons["tab_bse"].setCheckable(True)
self.buttons["tab_bse"].setChecked(True)
- self.buttons["tab_key"] = QtWidgets.QPushButton(get_text("KEY", "KEY"))
+ self.buttons["tab_key"] = QtWidgets.QPushButton(TEXT("KEY", "KEY"))
self.buttons["tab_key"].setIcon(ui_utils.load_icon("setKeyOnAnim.png"))
self.buttons["tab_key"].setObjectName("tabKeyButton")
self.buttons["tab_key"].setCheckable(True)
self.buttons["tab_key"].setChecked(True)
- self.buttons["tab_mir"] = QtWidgets.QPushButton(get_text("MIR", "MIR"))
+ self.buttons["tab_mir"] = QtWidgets.QPushButton(TEXT("MIR", "MIR"))
self.buttons["tab_mir"].setIcon(ui_utils.load_icon("mirrorR.png"))
self.buttons["tab_mir"].setObjectName("tabMirButton")
self.buttons["tab_mir"].setCheckable(True)
self.buttons["tab_mir"].setChecked(True)
- self.buttons["tab_ark"] = QtWidgets.QPushButton(get_text("ARK", "ARK"))
+ self.buttons["tab_ark"] = QtWidgets.QPushButton(TEXT("ARK", "ARK"))
self.buttons["tab_ark"].setIcon(ui_utils.load_icon("ARKit52.png"))
self.buttons["tab_ark"].setObjectName("tabArkButton")
self.buttons["tab_ark"].setCheckable(True)
self.buttons["tab_ark"].setChecked(True)
- self.buttons["tab_ctr"] = QtWidgets.QPushButton(get_text("CTR", "CTR"))
+ self.buttons["tab_ctr"] = QtWidgets.QPushButton(TEXT("CTR", "CTR"))
self.buttons["tab_ctr"].setIcon(ui_utils.load_icon("ctrl_hide.png"))
self.buttons["tab_ctr"].setObjectName("tabCtrButton")
self.buttons["tab_ctr"].setCheckable(True)
self.buttons["tab_ctr"].setChecked(True)
# 底部功能按钮
- self.buttons["reset_default_expression"] = QtWidgets.QPushButton(get_text("Reset Default", "重置默认"))
+ self.buttons["reset_default_expression"] = QtWidgets.QPushButton(TEXT("Reset Default", "重置默认"))
self.buttons["reset_default_expression"].setIcon(ui_utils.load_icon("reset.png"))
self.buttons["reset_default_expression"].setObjectName("resetDefaultExpressionButton")
- self.buttons["find_select_expression"] = QtWidgets.QPushButton(get_text("Find Select", "查找选择"))
+ self.buttons["find_select_expression"] = QtWidgets.QPushButton(TEXT("Find Select", "查找选择"))
self.buttons["find_select_expression"].setIcon(ui_utils.load_icon("expressions_current.png"))
self.buttons["find_select_expression"].setObjectName("findSelectExpressionButton")
- self.buttons["write_current_expressions"] = QtWidgets.QPushButton(get_text("Write Current", "写入当前"))
+ self.buttons["write_current_expressions"] = QtWidgets.QPushButton(TEXT("Write Current", "写入当前"))
self.buttons["write_current_expressions"].setIcon(ui_utils.load_icon("expression.png"))
self.buttons["write_current_expressions"].setObjectName("writeCurrentExpressionsButton")
- self.buttons["controller_find"] = QtWidgets.QPushButton(get_text("Controller Find", "控制器查找"))
+ self.buttons["controller_find"] = QtWidgets.QPushButton(TEXT("Controller Find", "控制器查找"))
self.buttons["controller_find"].setIcon(ui_utils.load_icon("controller.png"))
self.buttons["controller_find"].setObjectName("controllerFindButton")
- self.buttons["select_associated_joint"] = QtWidgets.QPushButton(get_text("Select Joint", "选择关节"))
+ self.buttons["select_associated_joint"] = QtWidgets.QPushButton(TEXT("Select Joint", "选择关节"))
self.buttons["select_associated_joint"].setIcon(ui_utils.load_icon("out_joint.png"))
self.buttons["select_associated_joint"].setObjectName("selectAssociatedJointButton")
- self.buttons["write_find_mirror"] = QtWidgets.QPushButton(get_text("Find Mirror", "查找镜像"))
+ self.buttons["write_find_mirror"] = QtWidgets.QPushButton(TEXT("Find Mirror", "查找镜像"))
self.buttons["write_find_mirror"].setIcon(ui_utils.load_icon("mirror.png"))
self.buttons["write_find_mirror"].setObjectName("writeFindMirrorButton")
@@ -417,7 +395,7 @@ class BehaviourUI(ui_utils.BaseUI):
self.layouts["left_content_layout"].setSpacing(5)
# 添加标题标签
- left_title = QtWidgets.QLabel(get_text("Raw Control", "原始控制"))
+ left_title = QtWidgets.QLabel(TEXT("Raw Control", "原始控制"))
left_title.setStyleSheet("font-weight: bold;")
self.layouts["left_content_layout"].addWidget(left_title)
@@ -481,7 +459,7 @@ class BehaviourUI(ui_utils.BaseUI):
self.layouts["right_content_layout"].setSpacing(5)
# 添加标题标签
- right_title = QtWidgets.QLabel(get_text("Related BlendShapes", "相关BlendShapes"))
+ right_title = QtWidgets.QLabel(TEXT("Related BlendShapes", "相关BlendShapes"))
right_title.setStyleSheet("font-weight: bold;")
self.layouts["right_content_layout"].addWidget(right_title)
diff --git a/scripts/ui/definition.py b/scripts/ui/definition.py
index 3faf97b..ffa8485 100644
--- a/scripts/ui/definition.py
+++ b/scripts/ui/definition.py
@@ -11,8 +11,8 @@ Definition UI Module for Plugin
- 工具:重新定位头部关节,重新定位身体关节,重新定位全身关节,快速创建预设
"""
#========================================= IMPORT =========================================
-from Qt import QtWidgets, QtCore, QtGui
-from Qt.QtCompat import wrapInstance
+from scripts.ui.Qt import QtWidgets, QtCore, QtGui
+from scripts.ui.Qt.QtCompat import wrapInstance
from maya import OpenMayaUI as omui
import maya.cmds as cmds
import maya.mel as mel
@@ -51,8 +51,7 @@ TOOL_WIDTH = config.TOOL_WIDTH
TOOL_HEIGHT = config.TOOL_HEIGHT
#========================================= LOCATION =======================================
from scripts.ui import localization
-LANG = localization.LANG
-get_text = localization.get_text
+TEXT = localization.TEXT
class DefinitionUI(ui_utils.BaseUI):
"""
@@ -64,27 +63,19 @@ class DefinitionUI(ui_utils.BaseUI):
"""
初始化定义系统UI
"""
- super(DefinitionUI, self).__init__() # 不传递parent参数给BaseUI
-
- # 设置单例实例
- DefinitionUI._instance = self
+ super().__init__(parent)
# 创建主控件
- self.main_widget = QtWidgets.QWidget(parent)
+ self.main_widget = QtWidgets.QWidget()
self.main_widget.setObjectName("definitionMainWidget")
- # 初始化控件、布局和按钮字典
- self.controls = {}
- self.layouts = {}
- self.buttons = {}
- self.splitters = {}
-
# 创建UI组件
self.create_widgets()
self.create_layouts()
self.create_connections()
-
- # 注意:移除了这里的分割器元素添加代码
+
+ # 更新UI文本
+ self.update_language()
#========================================= WIDGET =======================================
def create_widgets(self):
@@ -93,7 +84,7 @@ class DefinitionUI(ui_utils.BaseUI):
包括按钮、标签、列表等
"""
# 标题标签 - 使用HTML格式化标题
- title_text = f"
{get_text('definition_title', 'DNA定义')}
"
+ title_text = f"{TEXT('definition_title', 'DNA定义')}
"
self.controls["title_label"] = QtWidgets.QLabel(title_text)
self.controls["title_label"].setObjectName("definitionTitleLabel")
self.controls["title_label"].setAlignment(QtCore.Qt.AlignCenter)
@@ -124,7 +115,7 @@ class DefinitionUI(ui_utils.BaseUI):
self.controls["lods_list"].setObjectName("lodsList")
# 定义LOD关联按钮
- self.buttons["define_lod_relations"] = QtWidgets.QPushButton(get_text("define_lod_relations", "定义LOD关联"))
+ self.buttons["define_lod_relations"] = QtWidgets.QPushButton(TEXT("define_lod_relations", "定义LOD关联"))
self.buttons["define_lod_relations"].setIcon(ui_utils.load_icon("layerEditor.png"))
self.buttons["define_lod_relations"].setObjectName("defineLodRelationsButton")
@@ -137,7 +128,7 @@ class DefinitionUI(ui_utils.BaseUI):
self.controls["meshes_list"].setObjectName("meshesList")
# 创建几何体按钮
- self.buttons["create_geometry"] = QtWidgets.QPushButton(get_text("create_geometry", "创建几何体"))
+ self.buttons["create_geometry"] = QtWidgets.QPushButton(TEXT("create_geometry", "创建几何体"))
self.buttons["create_geometry"].setIcon(ui_utils.load_icon("polyCube.png"))
self.buttons["create_geometry"].setObjectName("createGeometryButton")
@@ -168,61 +159,61 @@ class DefinitionUI(ui_utils.BaseUI):
# 底部工具面板
# 写入部分
- self.controls["write_label"] = QtWidgets.QLabel(get_text("Write", "写入"))
+ self.controls["write_label"] = QtWidgets.QLabel(TEXT("Write", "写入"))
self.controls["write_label"].setObjectName("WriteLabel")
self.controls["write_label"].setAlignment(QtCore.Qt.AlignCenter)
- self.buttons["write_neutral_pose_joint_position"] = QtWidgets.QPushButton(get_text("Write Neutral Pose Joint Position", "写入中性Pose关节位置"))
+ self.buttons["write_neutral_pose_joint_position"] = QtWidgets.QPushButton(TEXT("Write Neutral Pose Joint Position", "写入中性Pose关节位置"))
self.buttons["write_neutral_pose_joint_position"].setIcon(ui_utils.load_icon("HIKCharacterToolBodyPart.png"))
self.buttons["write_neutral_pose_joint_position"].setObjectName("WriteNeutralPoseJointPositionButton")
- self.buttons["write_geometry"] = QtWidgets.QPushButton(get_text("Write Geometry", "写入几何体"))
+ self.buttons["write_geometry"] = QtWidgets.QPushButton(TEXT("Write Geometry", "写入几何体"))
self.buttons["write_geometry"].setIcon(ui_utils.load_icon("polyCube.png"))
self.buttons["write_geometry"].setObjectName("WriteGeometryButton")
- self.buttons["write_skin_weight"] = QtWidgets.QPushButton(get_text("Write Skin Weight", "写入蒙皮权重"))
+ self.buttons["write_skin_weight"] = QtWidgets.QPushButton(TEXT("Write Skin Weight", "写入蒙皮权重"))
self.buttons["write_skin_weight"].setIcon(ui_utils.load_icon("paintSkinWeights.png"))
self.buttons["write_skin_weight"].setObjectName("WriteSkinWeightButton")
- self.buttons["write_blendshape_target"] = QtWidgets.QPushButton(get_text("Write Blendshape Target", "写入BS对象"))
+ self.buttons["write_blendshape_target"] = QtWidgets.QPushButton(TEXT("Write Blendshape Target", "写入BS对象"))
self.buttons["write_blendshape_target"].setIcon(ui_utils.load_icon("blendShape.png"))
self.buttons["write_blendshape_target"].setObjectName("WriteBlendshapeTargetButton")
# 创建部分
- self.controls["create_label"] = QtWidgets.QLabel(get_text("Create", "创建"))
+ self.controls["create_label"] = QtWidgets.QLabel(TEXT("Create", "创建"))
self.controls["create_label"].setObjectName("CreateLabel")
self.controls["create_label"].setAlignment(QtCore.Qt.AlignCenter)
- self.buttons["create_blendshapes_for_mesh"] = QtWidgets.QPushButton(get_text("Create Blendshapes For Mesh", "为模型创建Blendshape"))
+ self.buttons["create_blendshapes_for_mesh"] = QtWidgets.QPushButton(TEXT("Create Blendshapes For Mesh", "为模型创建Blendshape"))
self.buttons["create_blendshapes_for_mesh"].setIcon(ui_utils.load_icon("blendShapeEditor.png"))
self.buttons["create_blendshapes_for_mesh"].setObjectName("CreateBlendshapeForMeshButton")
- self.buttons["create_skin_for_mesh"] = QtWidgets.QPushButton(get_text("Create Skin For Mesh", "为模型创建绑定蒙皮"))
+ self.buttons["create_skin_for_mesh"] = QtWidgets.QPushButton(TEXT("Create Skin For Mesh", "为模型创建绑定蒙皮"))
self.buttons["create_skin_for_mesh"].setIcon(ui_utils.load_icon("smoothSkin.png"))
self.buttons["create_skin_for_mesh"].setObjectName("CreateSkinForMeshButton")
- self.buttons["unbind_skin_for_mesh"] = QtWidgets.QPushButton(get_text("Unbind Skin For Mesh", "为模型取消绑定蒙皮"))
+ self.buttons["unbind_skin_for_mesh"] = QtWidgets.QPushButton(TEXT("Unbind Skin For Mesh", "为模型取消绑定蒙皮"))
self.buttons["unbind_skin_for_mesh"].setIcon(ui_utils.load_icon("detachSkin.png"))
self.buttons["unbind_skin_for_mesh"].setObjectName("UnbindSkinForMeshButton")
# 工具部分
- self.controls["tools_label"] = QtWidgets.QGroupBox(get_text("Tools", "工具"))
+ self.controls["tools_label"] = QtWidgets.QGroupBox(TEXT("Tools", "工具"))
self.controls["tools_label"].setObjectName("ToolsLabel")
self.controls["tools_label"].setAlignment(QtCore.Qt.AlignCenter)
- self.buttons["new_head_netural_joint_transform"] = QtWidgets.QPushButton(get_text("New Head Netural Joint Transform", "重新定位头部关节"))
+ self.buttons["new_head_netural_joint_transform"] = QtWidgets.QPushButton(TEXT("New Head Netural Joint Transform", "重新定位头部关节"))
self.buttons["new_head_netural_joint_transform"].setIcon(ui_utils.load_icon("HIKCharacterToolSkeleton.png"))
self.buttons["new_head_netural_joint_transform"].setObjectName("NewHeadNeturalJointTransformButton")
- self.buttons["new_body_netural_joint_transform"] = QtWidgets.QPushButton(get_text("New Body Netural Joint Transform", "重新定位身体关节"))
+ self.buttons["new_body_netural_joint_transform"] = QtWidgets.QPushButton(TEXT("New Body Netural Joint Transform", "重新定位身体关节"))
self.buttons["new_body_netural_joint_transform"].setIcon(ui_utils.load_icon("HIKCharacterToolSkeleton.png"))
self.buttons["new_body_netural_joint_transform"].setObjectName("NewBodyNeturalJointTransformButton")
- self.buttons["new_netural_joint_transform"] = QtWidgets.QPushButton(get_text("New Netural Joint Transform", "重新定位全身关节"))
+ self.buttons["new_netural_joint_transform"] = QtWidgets.QPushButton(TEXT("New Netural Joint Transform", "重新定位全身关节"))
self.buttons["new_netural_joint_transform"].setIcon(ui_utils.load_icon("HIKCharacterToolSkeleton.png"))
self.buttons["new_netural_joint_transform"].setObjectName("NewNeturalJointTransformButton")
- self.buttons["quick_create_preset"] = QtWidgets.QPushButton(get_text("Quick Create Preset", "快速创建预设"))
+ self.buttons["quick_create_preset"] = QtWidgets.QPushButton(TEXT("Quick Create Preset", "快速创建预设"))
self.buttons["quick_create_preset"].setIcon(ui_utils.load_icon("QR_QuickRigTool.png"))
self.buttons["quick_create_preset"].setObjectName("QuickCreatePreset")
@@ -324,7 +315,7 @@ class DefinitionUI(ui_utils.BaseUI):
self.layouts["bottom_panel"].setSpacing(10)
# 写入部分QGroupBox
- self.controls["write_group"] = QtWidgets.QGroupBox(get_text("Write", "写入"))
+ self.controls["write_group"] = QtWidgets.QGroupBox(TEXT("Write", "写入"))
self.controls["write_group"].setObjectName("writeGroup")
self.layouts["write_layout"] = QtWidgets.QVBoxLayout()
self.layouts["write_layout"].setSpacing(5)
@@ -336,7 +327,7 @@ class DefinitionUI(ui_utils.BaseUI):
self.controls["write_group"].setLayout(self.layouts["write_layout"])
# 创建部分QGroupBox
- self.controls["create_group"] = QtWidgets.QGroupBox(get_text("Create", "创建"))
+ self.controls["create_group"] = QtWidgets.QGroupBox(TEXT("Create", "创建"))
self.controls["create_group"].setObjectName("createGroup")
self.layouts["create_layout"] = QtWidgets.QVBoxLayout()
self.layouts["create_layout"].setSpacing(5)
@@ -347,7 +338,7 @@ class DefinitionUI(ui_utils.BaseUI):
self.controls["create_group"].setLayout(self.layouts["create_layout"])
# 工具部分QGroupBox
- self.controls["tools_group"] = QtWidgets.QGroupBox(get_text("Tools", "工具"))
+ self.controls["tools_group"] = QtWidgets.QGroupBox(TEXT("Tools", "工具"))
self.controls["tools_group"].setObjectName("toolsGroup")
self.layouts["tools_layout"] = QtWidgets.QVBoxLayout()
self.layouts["tools_layout"].setSpacing(5)
diff --git a/scripts/ui/geometry.py b/scripts/ui/geometry.py
index b0415ab..28d9d3c 100644
--- a/scripts/ui/geometry.py
+++ b/scripts/ui/geometry.py
@@ -16,8 +16,8 @@ Geometry UI Module for Plugin
- 修复点序
"""
#========================================= IMPORT =========================================
-from Qt import QtWidgets, QtCore, QtGui
-from Qt.QtCompat import wrapInstance
+from scripts.ui.Qt import QtWidgets, QtCore, QtGui
+from scripts.ui.Qt.QtCompat import wrapInstance
from maya import OpenMayaUI as omui
import maya.cmds as cmds
import maya.mel as mel
@@ -56,22 +56,16 @@ TOOL_WIDTH = config.TOOL_WIDTH
TOOL_HEIGHT = config.TOOL_HEIGHT
#========================================= LOCATION =======================================
from scripts.ui import localization
-LANG = localization.LANG
-get_text = localization.get_text
+TEXT = localization.TEXT
class GeometryUI(ui_utils.BaseUI):
"""
几何模型UI类 - 负责显示几何模型编辑界面和基础操作
继承自BaseUI类,实现几何模型相关的UI功能
"""
- #========================================== INIT ========================================
- def __init__(self):
- """
- 初始化几何模型UI
- 创建主控件和布局,并连接信号和槽
- """
- super(GeometryUI, self).__init__()
-
+ # 只继承BaseUI,不自定义单例相关代码
+ def __init__(self, parent=None):
+ super().__init__(parent)
# 创建主控件
self.main_widget = QtWidgets.QWidget()
self.main_widget.setObjectName("geometryMainWidget")
@@ -80,6 +74,9 @@ class GeometryUI(ui_utils.BaseUI):
self.create_widgets()
self.create_layouts()
self.create_connections()
+
+ # 更新UI文本
+ self.update_language()
#========================================= WIDGET =======================================
def create_widgets(self):
@@ -88,7 +85,7 @@ class GeometryUI(ui_utils.BaseUI):
包括按钮、标签、列表等
"""
# 标题标签 - 使用HTML格式化标题
- title_text = f"{get_text('geometry_title', '几何模型')}
"
+ title_text = f"{TEXT('geometry_title', '几何模型')}
"
self.controls["title_label"] = QtWidgets.QLabel(title_text)
self.controls["title_label"].setObjectName("geometryTitleLabel")
self.controls["title_label"].setAlignment(QtCore.Qt.AlignCenter)
@@ -107,115 +104,6 @@ class GeometryUI(ui_utils.BaseUI):
# 创建底部功能按钮区域
self.create_bottom_buttons()
-
- # 模型列表
- self.controls["model_list"] = QtWidgets.QListWidget()
- self.controls["model_list"].setObjectName("modelList")
-
- # 模型操作按钮
- self.buttons["add_model"] = QtWidgets.QPushButton(get_text("add_model", "添加模型"))
- self.buttons["add_model"].setObjectName("addModelButton")
-
- self.buttons["remove_model"] = QtWidgets.QPushButton(get_text("remove_model", "移除模型"))
- self.buttons["remove_model"].setObjectName("removeModelButton")
-
- self.buttons["duplicate_model"] = QtWidgets.QPushButton(get_text("duplicate_model", "复制模型"))
- self.buttons["duplicate_model"].setObjectName("duplicateModelButton")
-
- # 右侧面板控件 - 模型属性
- self.controls["model_properties_group"] = QtWidgets.QGroupBox(get_text("model_properties", "模型属性"))
- self.controls["model_properties_group"].setObjectName("modelPropertiesGroup")
-
- # 模型名称标签和输入框
- self.controls["model_name_label"] = QtWidgets.QLabel(get_text("name", "名称:"))
- self.controls["model_name_label"].setObjectName("modelNameLabel")
-
- self.controls["model_name_input"] = QtWidgets.QLineEdit()
- self.controls["model_name_input"].setObjectName("modelNameInput")
- self.controls["model_name_input"].setPlaceholderText(get_text("enter_model_name", "输入模型名称"))
-
- # 模型类型标签和下拉框
- self.controls["model_type_label"] = QtWidgets.QLabel(get_text("type", "类型:"))
- self.controls["model_type_label"].setObjectName("modelTypeLabel")
-
- self.controls["model_type_combo"] = QtWidgets.QComboBox()
- self.controls["model_type_combo"].setObjectName("modelTypeCombo")
- self.controls["model_type_combo"].addItems(["Base", "Head", "Body", "Accessory", "Other"])
-
- # 模型可见性复选框
- self.controls["model_visible_check"] = QtWidgets.QCheckBox(get_text("visible", "可见"))
- self.controls["model_visible_check"].setObjectName("modelVisibleCheck")
- self.controls["model_visible_check"].setChecked(True)
-
- # 模型属性按钮
- self.buttons["apply_properties"] = QtWidgets.QPushButton(get_text("apply", "应用"))
- self.buttons["apply_properties"].setObjectName("applyPropertiesButton")
-
- self.buttons["reset_properties"] = QtWidgets.QPushButton(get_text("reset", "重置"))
- self.buttons["reset_properties"].setObjectName("resetPropertiesButton")
-
- # 右侧面板控件 - 模型工具
- self.controls["model_tools_group"] = QtWidgets.QGroupBox(get_text("model_tools", "模型工具"))
- self.controls["model_tools_group"].setObjectName("modelToolsGroup")
-
- # 模型工具按钮
- self.buttons["standardize_names"] = QtWidgets.QPushButton(get_text("standardize_names", "标准化命名"))
- self.buttons["standardize_names"].setObjectName("standardizeNamesButton")
-
- self.buttons["auto_group"] = QtWidgets.QPushButton(get_text("auto_group", "自动分组"))
- self.buttons["auto_group"].setObjectName("autoGroupButton")
-
- self.buttons["generate_accessories"] = QtWidgets.QPushButton(get_text("generate_accessories", "生成配件"))
- self.buttons["generate_accessories"].setObjectName("generateAccessoriesButton")
-
- self.buttons["fix_seams"] = QtWidgets.QPushButton(get_text("fix_seams", "修复接缝"))
- self.buttons["fix_seams"].setObjectName("fixSeamsButton")
-
- self.buttons["fix_vertex_order"] = QtWidgets.QPushButton(get_text("fix_vertex_order", "修复点序"))
- self.buttons["fix_vertex_order"].setObjectName("fixVertexOrderButton")
-
- # 底部工具面板
- # 导入部分
- self.controls["import_group"] = QtWidgets.QGroupBox(get_text("import", "导入"))
- self.controls["import_group"].setObjectName("importGroup")
-
- self.buttons["import_model"] = QtWidgets.QPushButton(get_text("import_model", "导入模型"))
- self.buttons["import_model"].setObjectName("importModelButton")
-
- self.buttons["import_fbx"] = QtWidgets.QPushButton(get_text("import_fbx", "导入FBX"))
- self.buttons["import_fbx"].setObjectName("importFbxButton")
-
- self.buttons["import_obj"] = QtWidgets.QPushButton(get_text("import_obj", "导入OBJ"))
- self.buttons["import_obj"].setObjectName("importObjButton")
-
- # 导出部分
- self.controls["export_group"] = QtWidgets.QGroupBox(get_text("export", "导出"))
- self.controls["export_group"].setObjectName("exportGroup")
-
- self.buttons["export_model"] = QtWidgets.QPushButton(get_text("export_model", "导出模型"))
- self.buttons["export_model"].setObjectName("exportModelButton")
-
- self.buttons["export_fbx"] = QtWidgets.QPushButton(get_text("export_fbx", "导出 FBX"))
- self.buttons["export_fbx"].setObjectName("exportFbxButton")
-
- self.buttons["export_obj"] = QtWidgets.QPushButton(get_text("export_obj", "导出 OBJ"))
- self.buttons["export_obj"].setObjectName("exportObjButton")
-
- # 工具部分
- self.controls["tools_group"] = QtWidgets.QGroupBox(get_text("tools", "工具"))
- self.controls["tools_group"].setObjectName("toolsGroup")
-
- self.buttons["check_model"] = QtWidgets.QPushButton(get_text("check_model", "检查模型"))
- self.buttons["check_model"].setObjectName("checkModelButton")
-
- self.buttons["optimize_model"] = QtWidgets.QPushButton(get_text("optimize_model", "优化模型"))
- self.buttons["optimize_model"].setObjectName("optimizeModelButton")
-
- self.buttons["clean_model"] = QtWidgets.QPushButton(get_text("clean_model", "清理模型"))
- self.buttons["clean_model"].setObjectName("cleanModelButton")
-
- self.buttons["uv_tools"] = QtWidgets.QPushButton(get_text("uv_tools", "UV工具"))
- self.buttons["uv_tools"].setObjectName("uvToolsButton")
def create_lod_tabs(self):
"""
@@ -274,15 +162,15 @@ class GeometryUI(ui_utils.BaseUI):
# 输入框
line_edit = QtWidgets.QLineEdit()
- line_edit.setPlaceholderText(get_text("enter_model_name", "输入模型名称"))
+ line_edit.setPlaceholderText(TEXT("enter_model_name", "输入模型名称"))
line_edit.setObjectName(f"{lod_name}_{part}_input")
- # 创建加载按钮(统一插件风格)
- load_button = QtWidgets.QPushButton(get_text(" load ", " 加 载 "))
- load_button.setObjectName("{TOOL_NAME}LoadButton")
+ # 创建加载按钮(统一风格)
+ load_button = QtWidgets.QPushButton(TEXT("load", " 加 载 "))
+ load_button.setObjectName("LoadButton")
load_button.setIcon(QtGui.QIcon(os.path.join(ICONS_PATH, "loading.png")))
load_button.setIconSize(QtCore.QSize(16, 16))
- load_button.setToolTip(get_text("load_model", "加载模型"))
+ load_button.setToolTip(TEXT("load_model", "加载模型"))
load_button.setFixedSize(105, 24) # 更紧凑,和输入框高度完全一致
load_button.setStyleSheet("""
QPushButton {
@@ -308,24 +196,57 @@ class GeometryUI(ui_utils.BaseUI):
# 添加弹性空间
tab_layout.addStretch(1)
-
+
+ # === 添加LOD专属底部三大按钮 ===
+ lod_buttons_layout = QtWidgets.QHBoxLayout()
+ lod_buttons_layout.setContentsMargins(0, 0, 0, 0)
+ lod_buttons_layout.setSpacing(10)
+
+ btn_auto_load = QtWidgets.QPushButton(TEXT("auto_load_meshes", "自动加载模型"))
+ btn_auto_load.setIcon(ui_utils.load_icon("load_meshes.png"))
+ btn_auto_load.setIconSize(QtCore.QSize(20, 20))
+ btn_auto_load.setObjectName(f"{lod_name}_autoLoadMeshesButton")
+ btn_auto_load.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
+
+ btn_standardized = QtWidgets.QPushButton(TEXT("standardized_naming", "标准化命名"))
+ btn_standardized.setIcon(ui_utils.load_icon("standardized_naming.png"))
+ btn_standardized.setIconSize(QtCore.QSize(20, 20))
+ btn_standardized.setObjectName(f"{lod_name}_standardizedNamingButton")
+ btn_standardized.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
+
+ btn_auto_group = QtWidgets.QPushButton(TEXT("automatic_grouping", "自动分组"))
+ btn_auto_group.setIcon(ui_utils.load_icon("automatic_grouping.png"))
+ btn_auto_group.setIconSize(QtCore.QSize(20, 20))
+ btn_auto_group.setObjectName(f"{lod_name}_automaticGroupingButton")
+ btn_auto_group.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
+
+ lod_buttons_layout.addWidget(btn_auto_load, 1)
+ lod_buttons_layout.addWidget(btn_standardized, 1)
+ lod_buttons_layout.addWidget(btn_auto_group, 1)
+
+ tab_layout.addLayout(lod_buttons_layout)
+ # 保存引用(如需后续操作)
+ self.buttons[f"{lod_name}_auto_load_meshes"] = btn_auto_load
+ self.buttons[f"{lod_name}_standardized_naming"] = btn_standardized
+ self.buttons[f"{lod_name}_automatic_grouping"] = btn_auto_group
+
# 将标签页添加到标签页控件
self.controls["tab_widget"].addTab(tab, lod_name)
# 创建清理按钮
- self.buttons["clean"] = QtWidgets.QPushButton(get_text("clean", " 清 理 "))
- self.buttons["clean"].setObjectName("clearButton")
- self.buttons["clean"].setIcon(ui_utils.load_icon("delete.png"))
- self.buttons["clean"].setIconSize(QtCore.QSize(16, 16))
- self.buttons["clean"].setFixedSize(150, 28)
- self.buttons["clean"].setToolTip(get_text("clear_all_models", "清理所有模型"))
- self.buttons["clean"].setStyleSheet("""
+ self.buttons["clear"] = QtWidgets.QPushButton(TEXT("clear", " 清 理 "))
+ self.buttons["clear"].setObjectName("clearButton")
+ self.buttons["clear"].setIcon(ui_utils.load_icon("delete.png"))
+ self.buttons["clear"].setIconSize(QtCore.QSize(16, 16))
+ self.buttons["clear"].setFixedSize(150, 28)
+ self.buttons["clear"].setToolTip(TEXT("clear_all_models", "清理所有模型"))
+ self.buttons["clear"].setStyleSheet("""
QPushButton {
padding: 2px 2px;
margin: 0px 50px 0px 0px; /* 上右下左的边距,增加上边距避免与标签栏重叠 */
}
""")
- self.buttons["clean"].setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
+ self.buttons["clear"].setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
def create_bottom_buttons(self):
"""
@@ -344,7 +265,7 @@ class GeometryUI(ui_utils.BaseUI):
bottom_layout.setSpacing(5)
# 创建模型工具区域
- model_tools_group = QtWidgets.QGroupBox(get_text("model_tools", "模型工具"))
+ model_tools_group = QtWidgets.QGroupBox(TEXT("model_tools", "模型工具"))
model_tools_group.setObjectName("modelToolsGroup")
# 创建模型工具布局
@@ -365,7 +286,7 @@ class GeometryUI(ui_utils.BaseUI):
topology_container_layout = QtWidgets.QHBoxLayout(topology_container)
topology_container_layout.setContentsMargins(5, 5, 5, 5)
- topology_label = QtWidgets.QLabel(get_text("topology_structure", "拓扑结构") + ":")
+ topology_label = QtWidgets.QLabel(TEXT("topology_structure", "拓扑结构") + ":")
self.controls["topology_combo"] = QtWidgets.QComboBox()
self.controls["topology_combo"].setObjectName("topologyCombo")
self.controls["topology_combo"].addItem("MetaHuman")
@@ -379,10 +300,10 @@ class GeometryUI(ui_utils.BaseUI):
lod_container_layout = QtWidgets.QHBoxLayout(lod_container)
lod_container_layout.setContentsMargins(5, 5, 5, 5)
- lod_label = QtWidgets.QLabel(get_text("select_lod", "选择LOD") + ":")
+ lod_label = QtWidgets.QLabel(TEXT("select_lod", "选择LOD") + ":")
self.controls["lod_combo"] = QtWidgets.QComboBox()
self.controls["lod_combo"].setObjectName("lodCombo")
- self.controls["lod_combo"].addItem(get_text("all", "全部"))
+ self.controls["lod_combo"].addItem(TEXT("all", "全部"))
for i in range(8): # LOD0~LOD7
self.controls["lod_combo"].addItem(f"LOD{i}")
@@ -395,7 +316,7 @@ class GeometryUI(ui_utils.BaseUI):
button_container_layout = QtWidgets.QHBoxLayout(button_container)
button_container_layout.setContentsMargins(5, 5, 5, 5)
- self.buttons["create_lod"] = QtWidgets.QPushButton(get_text("create_lod", "创建LOD"))
+ self.buttons["create_lod"] = QtWidgets.QPushButton(TEXT("create_lod", "创建LOD"))
self.buttons["create_lod"].setObjectName("createLodButton")
self.buttons["create_lod"].setIcon(ui_utils.load_icon("create_lod.png"))
self.buttons["create_lod"].setMinimumHeight(30)
@@ -413,31 +334,26 @@ class GeometryUI(ui_utils.BaseUI):
# 将水平布局添加到模型工具布局
model_tools_layout.addLayout(self.layouts["top_row_layout"], 0, 0, 1, 5)
- # 创建模型工具按钮
- # 设置按钮的尺寸策略,使其均等撑满一行
+ # 保留原有按钮行布局
size_policy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
-
- # 创建每行按钮的布局
self.layouts["buttons_row1_layout"] = QtWidgets.QHBoxLayout()
self.layouts["buttons_row1_layout"].setContentsMargins(0, 0, 0, 0)
self.layouts["buttons_row1_layout"].setSpacing(10)
-
self.layouts["buttons_row2_layout"] = QtWidgets.QHBoxLayout()
self.layouts["buttons_row2_layout"].setContentsMargins(0, 0, 0, 0)
self.layouts["buttons_row2_layout"].setSpacing(10)
-
self.layouts["buttons_row3_layout"] = QtWidgets.QHBoxLayout()
self.layouts["buttons_row3_layout"].setContentsMargins(0, 0, 0, 0)
self.layouts["buttons_row3_layout"].setSpacing(10)
# 第一行按钮
- self.buttons["separate_model"] = QtWidgets.QPushButton(get_text("separate_model", "模型分离"))
+ self.buttons["separate_model"] = QtWidgets.QPushButton(TEXT("separate_model", "模型分离"))
self.buttons["separate_model"].setObjectName("separateModelButton")
self.buttons["separate_model"].setIcon(ui_utils.load_icon("polySplitVertex.png"))
self.buttons["separate_model"].setMinimumHeight(30)
self.buttons["separate_model"].setSizePolicy(size_policy)
- self.buttons["generate_face_components"] = QtWidgets.QPushButton(get_text("generate_face_components", "生成面部配件"))
+ self.buttons["generate_face_components"] = QtWidgets.QPushButton(TEXT("generate_face_components", "生成面部配件"))
self.buttons["generate_face_components"].setObjectName("generateFaceComponentsButton")
self.buttons["generate_face_components"].setIcon(ui_utils.load_icon("meshes.png"))
self.buttons["generate_face_components"].setMinimumHeight(30)
@@ -448,13 +364,13 @@ class GeometryUI(ui_utils.BaseUI):
self.layouts["buttons_row1_layout"].addWidget(self.buttons["generate_face_components"])
# 第二行按钮
- self.buttons["fix_normals"] = QtWidgets.QPushButton(get_text("fix_normals", "修复法线"))
+ self.buttons["fix_normals"] = QtWidgets.QPushButton(TEXT("fix_normals", "修复法线"))
self.buttons["fix_normals"].setObjectName("fixNormalsButton")
self.buttons["fix_normals"].setIcon(ui_utils.load_icon("repair_normals.png"))
self.buttons["fix_normals"].setMinimumHeight(30)
self.buttons["fix_normals"].setSizePolicy(size_policy)
- self.buttons["fix_vertex_order"] = QtWidgets.QPushButton(get_text("fix_vertex_order", "修复点序"))
+ self.buttons["fix_vertex_order"] = QtWidgets.QPushButton(TEXT("fix_vertex_order", "修复点序"))
self.buttons["fix_vertex_order"].setObjectName("fixVertexOrderButton")
self.buttons["fix_vertex_order"].setIcon(ui_utils.load_icon("repair_vertex_order.png"))
self.buttons["fix_vertex_order"].setMinimumHeight(30)
@@ -465,13 +381,13 @@ class GeometryUI(ui_utils.BaseUI):
self.layouts["buttons_row2_layout"].addWidget(self.buttons["fix_vertex_order"])
# 第三行按钮
- self.buttons["fix_seams"] = QtWidgets.QPushButton(get_text("fix_seams", "修复接缝"))
+ self.buttons["fix_seams"] = QtWidgets.QPushButton(TEXT("fix_seams", "修复接缝"))
self.buttons["fix_seams"].setObjectName("fixSeamsButton")
self.buttons["fix_seams"].setIcon(ui_utils.load_icon("polyChipOff.png"))
self.buttons["fix_seams"].setMinimumHeight(30)
self.buttons["fix_seams"].setSizePolicy(size_policy)
- self.buttons["optimize_scene"] = QtWidgets.QPushButton(get_text("optimize_scene", "优化场景"))
+ self.buttons["optimize_scene"] = QtWidgets.QPushButton(TEXT("optimize_scene", "优化场景"))
self.buttons["optimize_scene"].setObjectName("optimizeSceneButton")
self.buttons["optimize_scene"].setIcon(ui_utils.load_icon("singlePerspLayout.png"))
self.buttons["optimize_scene"].setMinimumHeight(30)
@@ -505,7 +421,7 @@ class GeometryUI(ui_utils.BaseUI):
# 将清理按钮直接添加到标签页控件的右上角
# 设置标签页控件的角落部件
- self.controls["tab_widget"].setCornerWidget(self.buttons["clean"], QtCore.Qt.TopRightCorner)
+ self.controls["tab_widget"].setCornerWidget(self.buttons["clear"], QtCore.Qt.TopRightCorner)
# 添加标签页控件到主布局
self.layouts["main_layout"].addWidget(self.controls["tab_widget"])
@@ -563,7 +479,7 @@ class GeometryUI(ui_utils.BaseUI):
)
# 连接清理按钮
- self.buttons["clean"].clicked.connect(utils_geometry.clean)
+ self.buttons["clear"].clicked.connect(utils_geometry.clean)
# 连接拓扑结构下拉框
self.controls["topology_combo"].currentIndexChanged.connect(utils_geometry.update_topology)
diff --git a/scripts/ui/localization.py b/scripts/ui/localization.py
index 5a6fb3d..aaf47d9 100644
--- a/scripts/ui/localization.py
+++ b/scripts/ui/localization.py
@@ -13,124 +13,6 @@ current_language = config.TOOL_LANG # 默认使用中文
# 语言字典
LANG = {
- "en_US": {
- # 主界面
- "geometry": "Geometry",
- "rigging": "Rigging",
- "behaviour": "Behaviour",
- "definition": "Definition",
-
- # 几何体模块
- "geometry_title": "Geometry",
- "clean": " Clean ",
- "load": "Load mesh",
- "clear_all_models": " Clean all models",
- "add_model": "Add Model",
- "remove_model": "Remove Model",
- "duplicate_model": "Duplicate Model",
- "model_properties": "Model Properties",
- "model_tools": "Model Tools",
- "name": "Name",
- "enter_model_name": "Enter Model Name",
- "type": "Type",
- "visible": "Visible",
- "apply": "Apply",
- "reset": "Reset",
- "topology_structure": "Topology Structure",
- "select_lod": "Select LOD",
- "all": "All",
- "create_lod": "Create LOD",
- "separate_model": "Separate Model",
- "generate_face_components": "Generate Face Components",
- "fix_point_order": "Fix point order",
- "fix_normals": "Fix normal",
- "fix_vertex_order": "Fix vertex order",
- "fix_seams": "Fix seams",
- "standardize_naming": "Standardize Naming",
- "optimize_scene": "Optimize Scene",
- "auto_group": "Auto Group",
- "create_custom_lod": "Create Custom LOD",
- "import_lod": "Import LOD",
- "export_lod": "Export LOD",
- "search": "Search...",
-
- # 绑定模块
- "rigging_title": "Rigging System",
- "presets": "Presets",
- "assets": "Assets",
- "descriptor": "Descriptor",
- "project_path": "Project Path",
- "Presets DNA:": "Presets DNA:",
- "gender": "Gender",
- "age": "Age",
- "translation_unit": "Translation Unit",
- "rotation_unit": "Rotation Unit",
- "coordinate_system": "Coordinate System",
- "lod_count": "LOD Count",
- "archetype": "Archetype",
- "import_skeleton": "Import Skeleton",
- "build_rigging": "Build Rigging",
- "remove_all": "Remove All",
-
- # 行为模块
- "behaviour_title": "Behaviour System",
- "search": "Search...",
- " Range - ": " Range - ",
- " Range + ": " Range + ",
- "Raw Control": "Raw Control",
- "Related BlendShapes": "Related BlendShapes",
- "Add": "Add",
- "Delete": "Delete",
- "Batch": "Batch",
- "Rebuild": "Rebuild",
- "Reposition": "Reposition",
- "Blend": "Blend",
- "Flip Target": "Flip Target",
- "Mirror Target": "Mirror Target",
- "Find Flip Target": "Find Flip Target",
- "Add BlendShape": "Add BlendShape",
- "Delete BlendShape": "Delete BlendShape",
- "Batch BlendShape": "Batch BlendShape",
- "Rebuild Select": "Rebuild Select",
- "Reposition Joints": "Reposition Joints",
- "Blend Select": "Blend Select",
- "Reset Default": "Reset Default",
- "Find Select": "Find Select",
- "Write Current": "Write Current",
- "Controller Find": "Controller Find",
- "Select Joint": "Select Joint",
- "Find Mirror": "Find Mirror",
-
- # 定义模块
- "definition_title": "Definition System",
- "lods": "LODs",
- "meshes": "Meshes",
- "bones": "Bones",
- "name_pattern": "Name Pattern",
- "expression": "Expression",
- "add_lod": "Add LOD",
- "remove_lod": "Remove LOD",
- "duplicate_lod": "Duplicate LOD",
- "add_mesh": "Add Mesh",
- "remove_mesh": "Remove Mesh",
- "duplicate_mesh": "Duplicate Mesh",
- "add_bone": "Add Bone",
- "remove_bone": "Remove Bone",
- "duplicate_bone": "Duplicate Bone",
- "import_definition": "Import Definition",
- "export_definition": "Export Definition",
-
- # 工具栏
- "Save DNA": "Save DNA",
- "Open DNA": "Open DNA",
- "Create RL4 node": "Create RL4 Node",
- "Delete RL4 node": "Delete RL4 Node",
- "Import skin": "Import Skin",
- "Export skin": "Export Skin",
- "Copy skin": "Copy Skin",
- "Switch language": "Switch Language",
- "Help": "Help"
- },
"zh_CN": {
# 主界面
"geometry": "几何体",
@@ -140,55 +22,46 @@ LANG = {
# 几何体模块
"geometry_title": "几何模型",
- "clean": " 清 理 ",
- "load": " 加 载 ",
- "clear_all_models": " 清理所有模型",
- "add_model": "添加模型",
- "remove_model": "移除模型",
- "duplicate_model": "复制模型",
- "model_properties": "模型属性",
- "model_tools": "模型工具",
- "name": "名称",
"enter_model_name": "输入模型名称",
- "type": "类型",
- "visible": "可见",
- "apply": "应用",
- "reset": "重置",
+ "load": " 加 载 ",
+ "load_model": "加载模型",
+ "auto_load_meshes": "自动加载模型",
+ "standardized_naming": "标准化命名",
+ "automatic_grouping": "自动分组",
+ "clear": " 清 理 ",
+ "clear_all_models": "清理所有模型",
+ "model_tools": "模型工具",
"topology_structure": "拓扑结构",
"select_lod": "选择LOD",
"all": "全部",
"create_lod": "创建LOD",
"separate_model": "模型分离",
"generate_face_components": "生成面部配件",
- "fix_point_order": "修复点序",
"fix_normals": "修复法线",
"fix_vertex_order": "修复点序",
"fix_seams": "修复接缝",
- "standardize_naming": "标准化命名",
"optimize_scene": "优化场景",
- "auto_group": "自动分组",
- "create_custom_lod": "创建自定义LOD",
- "import_lod": "导入LOD",
- "export_lod": "导出LOD",
- "search": "搜索...",
# 绑定模块
"rigging_title": "绑定系统",
"presets": "预设",
- "assets": "资源",
- "descriptor": "描述器",
- "project_path": "项目路径",
+ "export_presets": "导出预设",
+ "import_presets": "导入预设",
+ "assets": "资产",
+ "project_path": "项目路径:",
"Presets DNA:": "预设 DNA:",
- "gender": "性别",
- "age": "年龄",
- "translation_unit": "平移单位",
- "rotation_unit": "旋转单位",
- "coordinate_system": "坐标系统",
- "lod_count": "LOD数量",
- "archetype": "原型",
+ "descriptor": "描述",
+ "name": "名称:",
+ "archetype": "原型:",
+ "gender": "性别:",
+ "age": "年龄:",
+ "translation_unit": "平移单位:",
+ "rotation_unit": "旋转单位:",
+ "coordinate_system": "坐标系统:",
+ "lod_count": "LOD数量:",
+ "remove_all": "移除全部",
"import_skeleton": "导入骨骼",
"build_rigging": "创建绑定",
- "remove_all": "移除全部",
# 行为模块
"behaviour_title": "行为系统",
@@ -221,23 +94,21 @@ LANG = {
# 定义模块
"definition_title": "定义系统",
- "lods": "级别细节",
- "meshes": "网格",
- "bones": "骨骼",
- "name_pattern": "命名模式",
- "expression": "表情",
- "add_lod": "添加LOD",
- "remove_lod": "移除LOD",
- "duplicate_lod": "复制LOD",
- "add_mesh": "添加网格",
- "remove_mesh": "移除网格",
- "duplicate_mesh": "复制网格",
- "add_bone": "添加骨骼",
- "remove_bone": "移除骨骼",
- "duplicate_bone": "复制骨骼",
- "import_definition": "导入定义",
- "export_definition": "导出定义",
-
+ "define_lod_relations": "定义LOD关联",
+ "create_geometry": "创建几何体",
+ "Write Neutral Pose Joint Position": "写入中性Pose关节位置",
+ "Write Geometry": "写入几何体",
+ "Write Skin Weight": "写入蒙皮权重",
+ "Write Blendshape Target": "写入BS对象",
+ "Create Blendshapes For Mesh": "为模型创建Blendshape",
+ "Create Skin For Mesh": "为模型创建绑定蒙皮",
+ "Unbind Skin For Mesh": "为模型取消绑定蒙皮",
+ "Tools": "工具",
+ "New Head Netural Joint Transform": "重新定位头部关节",
+ "New Body Netural Joint Transform": "重新定位身体关节",
+ "New Netural Joint Transform": "重新定位全身关节",
+ "Quick Create Preset": "快速创建预设",
+
# 工具栏
"保存DNA": "保存DNA",
"打开DNA": "打开DNA",
@@ -248,10 +119,117 @@ LANG = {
"复制蒙皮": "复制蒙皮",
"切换语言": "切换语言",
"帮助": "帮助"
+ },
+ "en_US": {
+ # Main Interface
+ "geometry": "Geometry",
+ "rigging": "Rigging",
+ "behaviour": "Behaviour",
+ "definition": "Definition",
+
+ # Geometry Module
+ "geometry_title": "Geometry Model",
+ "enter_model_name": "Enter Model Name",
+ "load": "Load",
+ "load_model": "Load Model",
+ "auto_load_meshes": "Auto Load Meshes",
+ "standardized_naming": "Standardized Naming",
+ "automatic_grouping": "Automatic Grouping",
+ "clear": "Clear",
+ "clear_all_models": "Clear All Models",
+ "model_tools": "Model Tools",
+ "topology_structure": "Topology Structure",
+ "select_lod": "Select LOD",
+ "all": "All",
+ "create_lod": "Create LOD",
+ "separate_model": "Separate Model",
+ "generate_face_components": "Generate Face Components",
+ "fix_normals": "Fix Normals",
+ "fix_vertex_order": "Fix Vertex Order",
+ "fix_seams": "Fix Seams",
+ "optimize_scene": "Optimize Scene",
+
+ # Rigging Module
+ "rigging_title": "Rigging System",
+ "presets": "Presets",
+ "export_presets": "Export Presets",
+ "import_presets": "Import Presets",
+ "assets": "Assets",
+ "project_path": "Project Path:",
+ "Presets DNA:": "Presets DNA:",
+ "descriptor": "Descriptor",
+ "name": "Name:",
+ "archetype": "Archetype:",
+ "gender": "Gender:",
+ "age": "Age:",
+ "translation_unit": "Translation Unit:",
+ "rotation_unit": "Rotation Unit:",
+ "coordinate_system": "Coordinate System:",
+ "lod_count": "LOD Count:",
+ "remove_all": "Remove All",
+ "import_skeleton": "Import Skeleton",
+ "build_rigging": "Build Rigging",
+
+ # Behaviour Module
+ "behaviour_title": "Behaviour System",
+ "search": "Search...",
+ " Range - ": " Range - ",
+ " Range + ": " Range + ",
+ "Raw Control": "Raw Control",
+ "Related BlendShapes": "Related BlendShapes",
+ "Add": "Add",
+ "Delete": "Delete",
+ "Batch": "Batch",
+ "Rebuild": "Rebuild",
+ "Reposition": "Reposition",
+ "Blend": "Blend",
+ "Flip Target": "Flip Target",
+ "Mirror Target": "Mirror Target",
+ "Find Flip Target": "Find Flip Target",
+ "Add BlendShape": "Add BlendShape",
+ "Delete BlendShape": "Delete BlendShape",
+ "Batch BlendShape": "Batch BlendShape",
+ "Rebuild Select": "Rebuild Select",
+ "Reposition Joints": "Reposition Joints",
+ "Blend Select": "Blend Select",
+ "Reset Default": "Reset Default",
+ "Find Select": "Find Select",
+ "Write Current": "Write Current",
+ "Controller Find": "Controller Find",
+ "Select Joint": "Select Joint",
+ "Find Mirror": "Find Mirror",
+
+ # Definition Module
+ "definition_title": "Definition System",
+ "define_lod_relations": "Define LOD Relations",
+ "create_geometry": "Create Geometry",
+ "Write Neutral Pose Joint Position": "Write Neutral Pose Joint Position",
+ "Write Geometry": "Write Geometry",
+ "Write Skin Weight": "Write Skin Weight",
+ "Write Blendshape Target": "Write BlendShape Target",
+ "Create Blendshapes For Mesh": "Create BlendShapes For Mesh",
+ "Create Skin For Mesh": "Create Skin For Mesh",
+ "Unbind Skin For Mesh": "Unbind Skin For Mesh",
+ "Tools": "Tools",
+ "New Head Netural Joint Transform": "Relocate Head Joint",
+ "New Body Netural Joint Transform": "Relocate Body Joint",
+ "New Netural Joint Transform": "Relocate All Joints",
+ "Quick Create Preset": "Quick Create Preset",
+
+ # Toolbar
+ "保存DNA": "Save DNA",
+ "打开DNA": "Open DNA",
+ "创建RL4节点": "Create RL4 Node",
+ "删除RL4节点": "Delete RL4 Node",
+ "导入蒙皮": "Import Skin",
+ "导出蒙皮": "Export Skin",
+ "复制蒙皮": "Copy Skin",
+ "切换语言": "Switch Language",
+ "帮助": "Help"
}
}
-def get_text(key, default=None):
+def TEXT(key, default=None):
"""
获取当前语言的文本
diff --git a/scripts/ui/rigging.py b/scripts/ui/rigging.py
index 30380ae..cc16e29 100644
--- a/scripts/ui/rigging.py
+++ b/scripts/ui/rigging.py
@@ -14,8 +14,8 @@ Rigging UI Module for Plugin
- 复制蒙皮
"""
#========================================= IMPORT =========================================
-from Qt import QtWidgets, QtCore, QtGui
-from Qt.QtCompat import wrapInstance
+from scripts.ui.Qt import QtWidgets, QtCore, QtGui
+from scripts.ui.Qt.QtCompat import wrapInstance
from maya import OpenMayaUI as omui
import maya.cmds as cmds
import maya.mel as mel
@@ -54,8 +54,7 @@ TOOL_WIDTH = config.TOOL_WIDTH
TOOL_HEIGHT = config.TOOL_HEIGHT
#========================================= LOCATION =======================================
from scripts.ui import localization
-LANG = localization.LANG
-get_text = localization.get_text
+TEXT = localization.TEXT
class RiggingUI(ui_utils.BaseUI):
"""
@@ -63,21 +62,13 @@ class RiggingUI(ui_utils.BaseUI):
继承自BaseUI类,实现绑定系统相关的UI功能
"""
#========================================== INIT ========================================
- def __init__(self):
+ def __init__(self, parent=None):
"""
初始化绑定系统UI
创建主控件和布局,并连接信号和槽
"""
- super(RiggingUI, self).__init__()
-
- # 初始化字典
- self.controls = {}
- self.layouts = {}
- self.buttons = {}
- self.splitters = {}
- self.inputs = {}
- self.labels = {}
-
+ super().__init__(parent)
+
# 创建主控件
self.main_widget = QtWidgets.QWidget()
self.main_widget.setObjectName("riggingMainWidget")
@@ -86,6 +77,9 @@ class RiggingUI(ui_utils.BaseUI):
self.create_widgets()
self.create_layouts()
self.create_connections()
+
+ # 更新UI文本
+ self.update_language()
#========================================= WIDGET =======================================
def create_widgets(self):
@@ -94,7 +88,7 @@ class RiggingUI(ui_utils.BaseUI):
包括按钮、标签、列表等
"""
# 标题标签 - 使用HTML格式化标题
- title_text = f"{get_text('rigging_title', '骨骼绑定')}
"
+ title_text = f"{TEXT('rigging_title', '骨骼绑定')}
"
self.controls["title_label"] = QtWidgets.QLabel(title_text)
self.controls["title_label"].setObjectName("riggingTitleLabel")
self.controls["title_label"].setAlignment(QtCore.Qt.AlignCenter)
@@ -109,7 +103,7 @@ class RiggingUI(ui_utils.BaseUI):
self.controls["presets_panel"].setObjectName("presetsPanel")
# Presets 组
- self.controls["presets_group"] = QtWidgets.QGroupBox(get_text("presets", "Presets"))
+ self.controls["presets_group"] = QtWidgets.QGroupBox(TEXT("presets", "Presets"))
self.controls["presets_group"].setObjectName("presetsGroup")
# 创建预设显示区域
@@ -190,12 +184,12 @@ class RiggingUI(ui_utils.BaseUI):
self.controls["presets_slider"].setValue(50)
# 导出预设按钮
- self.buttons["export_presets"] = QtWidgets.QPushButton(get_text("export_presets", "导出预设"))
+ self.buttons["export_presets"] = QtWidgets.QPushButton(TEXT("export_presets", "导出预设"))
self.buttons["export_presets"].setObjectName("exportPresetsButton")
self.buttons["export_presets"].setIcon(ui_utils.load_icon("export"))
# 导入预设按钮
- self.buttons["import_presets"] = QtWidgets.QPushButton(get_text("import_presets", "导入预设"))
+ self.buttons["import_presets"] = QtWidgets.QPushButton(TEXT("import_presets", "导入预设"))
self.buttons["import_presets"].setObjectName("importPresetsButton")
self.buttons["import_presets"].setIcon(ui_utils.load_icon("import"))
@@ -210,11 +204,11 @@ class RiggingUI(ui_utils.BaseUI):
self.controls["assets_panel"].setObjectName("assetsPanel")
# Assets 组
- self.controls["assets_group"] = QtWidgets.QGroupBox(get_text("assets", "Assets"))
+ self.controls["assets_group"] = QtWidgets.QGroupBox(TEXT("assets", "资产"))
self.controls["assets_group"].setObjectName("assetsGroup")
# 项目路径标签和输入框
- self.controls["project_path_label"] = QtWidgets.QLabel(get_text("project_path", "项目路径:"))
+ self.controls["project_path_label"] = QtWidgets.QLabel(TEXT("project_path", "项目路径:"))
self.controls["project_path_label"].setObjectName("projectPathLabel")
self.controls["project_path_input"] = QtWidgets.QLineEdit()
@@ -229,7 +223,7 @@ class RiggingUI(ui_utils.BaseUI):
self.buttons["browse_path"].setFixedWidth(100)
# Presets DNA 标签和输入框
- self.controls["presets_dna_label"] = QtWidgets.QLabel(get_text("Presets DNA:", "预设 DNA:"))
+ self.controls["presets_dna_label"] = QtWidgets.QLabel(TEXT("Presets DNA:", "预设 DNA:"))
self.controls["presets_dna_label"].setObjectName("presetsDnaLabel")
self.controls["presets_dna_input"] = QtWidgets.QLineEdit()
@@ -247,18 +241,18 @@ class RiggingUI(ui_utils.BaseUI):
self.controls["descriptor_panel"].setObjectName("descriptorPanel")
# Descriptor 组
- self.controls["descriptor_group"] = QtWidgets.QGroupBox(get_text("descriptor", "Descriptor"))
+ self.controls["descriptor_group"] = QtWidgets.QGroupBox(TEXT("descriptor", "描述"))
self.controls["descriptor_group"].setObjectName("descriptorGroup")
# 名称标签和输入框
- self.controls["name_label"] = QtWidgets.QLabel(get_text("name", "名称:"))
+ self.controls["name_label"] = QtWidgets.QLabel(TEXT("name", "名称:"))
self.controls["name_label"].setObjectName("nameLabel")
self.controls["name_input"] = QtWidgets.QLineEdit()
self.controls["name_input"].setObjectName("nameInput")
# 原型标签和下拉框
- self.controls["archetype_label"] = QtWidgets.QLabel(get_text("archetype", "原型:"))
+ self.controls["archetype_label"] = QtWidgets.QLabel(TEXT("archetype", "原型:"))
self.controls["archetype_label"].setObjectName("archetypeLabel")
self.controls["archetype_combo"] = QtWidgets.QComboBox()
@@ -268,7 +262,7 @@ class RiggingUI(ui_utils.BaseUI):
self.controls["archetype_combo"].addItem("african")
# 性别标签和下拉框
- self.controls["gender_label"] = QtWidgets.QLabel(get_text("gender", "性别:"))
+ self.controls["gender_label"] = QtWidgets.QLabel(TEXT("gender", "性别:"))
self.controls["gender_label"].setObjectName("genderLabel")
self.controls["gender_combo"] = QtWidgets.QComboBox()
@@ -277,7 +271,7 @@ class RiggingUI(ui_utils.BaseUI):
self.controls["gender_combo"].addItem("male")
# 年龄标签和输入框
- self.controls["age_label"] = QtWidgets.QLabel(get_text("age", "年龄:"))
+ self.controls["age_label"] = QtWidgets.QLabel(TEXT("age", "年龄:"))
self.controls["age_label"].setObjectName("ageLabel")
self.controls["age_spinner"] = QtWidgets.QSpinBox()
@@ -287,7 +281,7 @@ class RiggingUI(ui_utils.BaseUI):
self.controls["age_spinner"].setValue(24)
# 平移单位标签和下拉框
- self.controls["translation_unit_label"] = QtWidgets.QLabel(get_text("translation_unit", "平移单位:"))
+ self.controls["translation_unit_label"] = QtWidgets.QLabel(TEXT("translation_unit", "平移单位:"))
self.controls["translation_unit_label"].setObjectName("translationUnitLabel")
self.controls["translation_unit_combo"] = QtWidgets.QComboBox()
@@ -297,7 +291,7 @@ class RiggingUI(ui_utils.BaseUI):
self.controls["translation_unit_combo"].addItem("m")
# 旋转单位标签和下拉框
- self.controls["rotation_unit_label"] = QtWidgets.QLabel(get_text("rotation_unit", "旋转单位:"))
+ self.controls["rotation_unit_label"] = QtWidgets.QLabel(TEXT("rotation_unit", "旋转单位:"))
self.controls["rotation_unit_label"].setObjectName("rotationUnitLabel")
self.controls["rotation_unit_combo"] = QtWidgets.QComboBox()
@@ -306,7 +300,7 @@ class RiggingUI(ui_utils.BaseUI):
self.controls["rotation_unit_combo"].addItem("radians")
# 坐标系统标签和下拉框
- self.controls["coordinate_system_label"] = QtWidgets.QLabel(get_text("coordinate_system", "坐标系统:"))
+ self.controls["coordinate_system_label"] = QtWidgets.QLabel(TEXT("coordinate_system", "坐标系统:"))
self.controls["coordinate_system_label"].setObjectName("coordinateSystemLabel")
self.controls["coordinate_system_combo"] = QtWidgets.QComboBox()
@@ -315,7 +309,7 @@ class RiggingUI(ui_utils.BaseUI):
self.controls["coordinate_system_combo"].addItem("ZAxisUp")
# LOD数量标签和输入框
- self.controls["lod_count_label"] = QtWidgets.QLabel(get_text("lod_count", "LOD数量:"))
+ self.controls["lod_count_label"] = QtWidgets.QLabel(TEXT("lod_count", "LOD数量:"))
self.controls["lod_count_label"].setObjectName("lodCountLabel")
self.controls["lod_count_spinner"] = QtWidgets.QSpinBox()
@@ -329,17 +323,17 @@ class RiggingUI(ui_utils.BaseUI):
self.controls["bottom_buttons_panel"].setObjectName("bottomButtonsPanel")
# 删除所有按钮
- self.buttons["remove_all"] = QtWidgets.QPushButton(get_text("remove_all", "删除所有"))
+ self.buttons["remove_all"] = QtWidgets.QPushButton(TEXT("remove_all", "删除全部"))
self.buttons["remove_all"].setObjectName("removeAllButton")
self.buttons["remove_all"].setIcon(ui_utils.load_icon("delete.png"))
# 导入骨骼按钮
- self.buttons["import_skeleton"] = QtWidgets.QPushButton(get_text("import_skeleton", "导入骨骼"))
+ self.buttons["import_skeleton"] = QtWidgets.QPushButton(TEXT("import_skeleton", "导入骨骼"))
self.buttons["import_skeleton"].setObjectName("importSkeletonButton")
self.buttons["import_skeleton"].setIcon(ui_utils.load_icon("HIKCharacterToolSkeleton.png"))
# 生成绑定按钮
- self.buttons["build_rigging"] = QtWidgets.QPushButton(get_text("build_rigging", "生成绑定"))
+ self.buttons["build_rigging"] = QtWidgets.QPushButton(TEXT("build_rigging", "创建绑定"))
self.buttons["build_rigging"].setObjectName("buildRiggingButton")
self.buttons["build_rigging"].setIcon(ui_utils.load_icon("HIKcreateControlRig.png"))
diff --git a/scripts/ui/style.qss b/scripts/ui/style.qss
index ba5c826..a0ab76e 100644
--- a/scripts/ui/style.qss
+++ b/scripts/ui/style.qss
@@ -1,5 +1,4 @@
/* 插件样式表 */
-/* 作者: Virtuos Games */
/* 版本: Alpha v1.0.0 */
/* ==================== 全局样式 ==================== */
diff --git a/scripts/ui/toolbar.py b/scripts/ui/toolbar.py
index 6f520ac..01ed98b 100644
--- a/scripts/ui/toolbar.py
+++ b/scripts/ui/toolbar.py
@@ -13,8 +13,8 @@ Toolbar UI Module for Plugin
- 删除RL4节点(用于切换DNA编辑的状态)
"""
#========================================= IMPORT =========================================
-from Qt import QtWidgets, QtCore, QtGui
-from Qt.QtCompat import wrapInstance
+from scripts.ui.Qt import QtWidgets, QtCore, QtGui
+from scripts.ui.Qt.QtCompat import wrapInstance
from maya import OpenMayaUI as omui
import maya.cmds as cmds
import maya.mel as mel
@@ -28,7 +28,6 @@ import sys
import os
from scripts.ui import ui_utils
from scripts.utils import utils_toolbar
-from scripts.ui.localization import get_text
#========================================== CONFIG ========================================
import config
TOOL_NAME = config.TOOL_NAME
@@ -54,36 +53,20 @@ TOOL_WIDTH = config.TOOL_WIDTH
TOOL_HEIGHT = config.TOOL_HEIGHT
#========================================= LOCATION =======================================
from scripts.ui import localization
-LANG = localization.LANG
+TEXT = localization.TEXT
class ToolbarUI(ui_utils.BaseUI):
"""
工具栏UI类 - 负责显示工具栏界面和基础操作
继承自BaseUI类,实现工具栏相关的UI功能
"""
- # 类变量,存储单例实例
- _instance = None
-
- @classmethod
- def get_instance(cls):
- """
- 获取ToolbarUI的单例实例
-
- Returns:
- ToolbarUI: 单例实例,如果不存在则返回None
- """
- return cls._instance
-
#========================================== INIT ========================================
- def __init__(self):
+ def __init__(self, parent=None):
"""
初始化工具栏UI
创建主控件和布局,并连接信号和槽
"""
- super(ToolbarUI, self).__init__()
-
- # 设置单例实例
- ToolbarUI._instance = self
+ super().__init__(parent)
# 创建主控件
self.main_widget = QtWidgets.QWidget()
@@ -135,7 +118,7 @@ class ToolbarUI(ui_utils.BaseUI):
checkable: 是否可选中
"""
button = QtWidgets.QPushButton()
- button.setToolTip(get_text(tooltip, tooltip))
+ button.setToolTip(TEXT(tooltip, tooltip))
# 构建图标完整路径
icon_path = os.path.join(ICONS_PATH, icon_name)
@@ -146,7 +129,7 @@ class ToolbarUI(ui_utils.BaseUI):
button.setIconSize(QtCore.QSize(24, 24))
else:
# 如果图标不存在,使用文字
- button.setText(get_text(tooltip, tooltip))
+ button.setText(TEXT(tooltip, tooltip))
button.setObjectName(f"{tooltip.replace(' ', '_').lower()}_button")
button.setFixedSize(32, 32)
diff --git a/scripts/ui/ui_utils.py b/scripts/ui/ui_utils.py
index 4e94f87..59f4e68 100644
--- a/scripts/ui/ui_utils.py
+++ b/scripts/ui/ui_utils.py
@@ -6,8 +6,8 @@ UI Utilities Module for Plugin
UI工具模块 - 提供UI相关的通用函数
"""
#========================================= IMPORT =========================================
-from Qt import QtWidgets, QtCore, QtGui
-from Qt.QtCompat import wrapInstance
+from scripts.ui.Qt import QtWidgets, QtCore, QtGui
+from scripts.ui.Qt.QtCompat import wrapInstance
from maya import OpenMayaUI as omui
import maya.cmds as cmds
import maya.mel as mel
@@ -47,16 +47,15 @@ TOOL_HEIGHT = config.TOOL_HEIGHT
#========================================= LOCATION =======================================
from scripts.ui import localization
-LANG = localization.LANG
-
+TEXT = localization.TEXT
#============================================ UI BASE ==========================================
-class BaseUI(object):
+class BaseUI(QtWidgets.QWidget):
"""
UI基类
所有UI面板的基类,提供通用的UI功能
"""
- def __init__(self):
- """初始化UI基类"""
+ def __init__(self, parent=None):
+ super().__init__(parent)
# 初始化字典
self.controls = {}
self.layouts = {}
@@ -64,7 +63,6 @@ class BaseUI(object):
self.splitters = {}
self.inputs = {}
self.labels = {}
-
# 创建主控件
self.main_widget = None
@@ -82,10 +80,23 @@ class BaseUI(object):
def update_language(self):
"""
- 更新所有UI文本到当前语言
+ 递归刷新所有UI控件文本,支持多语言切换
"""
- if self.main_widget:
- update_ui_texts(self.main_widget)
+ from scripts.ui import localization
+ # 批量刷新注册字典中的控件
+ for group in [self.controls, self.labels, self.buttons, getattr(self, 'inputs', {}), getattr(self, 'splitters', {})]:
+ for key, widget in group.items():
+ # QLabel/QPushButton/QCheckBox/QRadioButton等
+ if hasattr(widget, 'setText'):
+ widget.setText(TEXT(key, widget.text() if hasattr(widget, 'text') else ""))
+ # QLineEdit等
+ elif hasattr(widget, 'setPlaceholderText'):
+ widget.setPlaceholderText(TEXT(key, widget.placeholderText() if hasattr(widget, 'placeholderText') else ""))
+ # 递归刷新所有自定义子UI(即BaseUI子类)
+ for child in self.findChildren(QtWidgets.QWidget):
+ if child is not self and hasattr(child, 'update_language') and callable(child.update_language):
+ child.update_language()
+
#============================================ UI HELPERS ==========================================
def connect_ui_signals(ui_instance, signal_mapping):
@@ -268,7 +279,7 @@ def update_ui_texts(widget):
for lang in ["zh_CN", "en_US"]:
for key, text in localization.LANG.get(lang, {}).items():
if text == current_text:
- widget.setText(localization.get_text(key, current_text))
+ widget.setText(TEXT(key, current_text))
break
# 更新按钮文本和工具提示
@@ -279,7 +290,7 @@ def update_ui_texts(widget):
for lang in ["zh_CN", "en_US"]:
for key, text in localization.LANG.get(lang, {}).items():
if text == current_text:
- widget.setText(localization.get_text(key, current_text))
+ widget.setText(TEXT(key, current_text))
break
# 更新工具提示
@@ -288,7 +299,7 @@ def update_ui_texts(widget):
for lang in ["zh_CN", "en_US"]:
for key, text in localization.LANG.get(lang, {}).items():
if text == current_tip:
- widget.setToolTip(localization.get_text(key, current_tip))
+ widget.setToolTip(TEXT(key, current_tip))
break
# 递归处理所有子控件
diff --git a/scripts/utils/utils_behaviour.py b/scripts/utils/utils_behaviour.py
index 7d4b7c8..75b837d 100644
--- a/scripts/utils/utils_behaviour.py
+++ b/scripts/utils/utils_behaviour.py
@@ -44,7 +44,7 @@ TOOL_WIDTH = config.TOOL_WIDTH
TOOL_HEIGHT = config.TOOL_HEIGHT
# Localization
from scripts.ui import localization
-LANG = localization.LANG
+TEXT = localization.TEXT
#========================================== FUNCTIONS ========================================
@@ -448,10 +448,10 @@ def update_raw_slider_value(value):
normalized_value = value / 100.0
# 获取UI实例并更新显示
- from scripts.ui.behaviour import BehaviourUI
- ui_instance = BehaviourUI.get_instance()
- if ui_instance and hasattr(ui_instance, 'controls'):
- ui_instance.controls["raw_slider_value"].setText(f"{normalized_value:.3f}")
+ from scripts.ui import behaviour
+ behaviour_ui = behaviour.BehaviourUI.get_instance()
+ if behaviour_ui and hasattr(behaviour_ui, 'controls'):
+ behaviour_ui.controls["raw_slider_value"].setText(f"{normalized_value:.3f}")
# 更新控制值
update_control_value(value)
@@ -472,10 +472,10 @@ def update_bs_slider_value(value):
normalized_value = value / 100.0
# 获取UI实例并更新显示
- from scripts.ui.behaviour import BehaviourUI
- ui_instance = BehaviourUI.get_instance()
- if ui_instance and hasattr(ui_instance, 'controls'):
- ui_instance.controls["bs_slider_value"].setText(f"{normalized_value:.3f}")
+ from scripts.ui import behaviour
+ behaviour_ui = behaviour.BehaviourUI.get_instance()
+ if behaviour_ui and hasattr(behaviour_ui, 'controls'):
+ behaviour_ui.controls["bs_slider_value"].setText(f"{normalized_value:.3f}")
# 更新BlendShape值
update_blendshape_value(value)
@@ -496,10 +496,10 @@ def update_bottom_slider_value(value):
normalized_value = value / 100.0
# 获取UI实例并更新显示
- from scripts.ui.behaviour import BehaviourUI
- ui_instance = BehaviourUI.get_instance()
- if ui_instance and hasattr(ui_instance, 'controls'):
- ui_instance.controls["bottom_slider_value"].setText(f"{normalized_value:.3f}")
+ from scripts.ui import behaviour
+ behaviour_ui = behaviour.BehaviourUI.get_instance()
+ if behaviour_ui and hasattr(behaviour_ui, 'controls'):
+ behaviour_ui.controls["bottom_slider_value"].setText(f"{normalized_value:.3f}")
# 更新主值
update_main_value(value)
diff --git a/scripts/utils/utils_definition.py b/scripts/utils/utils_definition.py
index 77a8eea..f579153 100644
--- a/scripts/utils/utils_definition.py
+++ b/scripts/utils/utils_definition.py
@@ -44,7 +44,7 @@ TOOL_WIDTH = config.TOOL_WIDTH
TOOL_HEIGHT = config.TOOL_HEIGHT
# Localization
from scripts.ui import localization
-LANG = localization.LANG
+TEXT = localization.TEXT
#========================================== FUNCTIONS ========================================
# 左侧面板功能
diff --git a/scripts/utils/utils_geometry.py b/scripts/utils/utils_geometry.py
index 3a7d7db..81ff915 100644
--- a/scripts/utils/utils_geometry.py
+++ b/scripts/utils/utils_geometry.py
@@ -44,7 +44,7 @@ TOOL_WIDTH = config.TOOL_WIDTH
TOOL_HEIGHT = config.TOOL_HEIGHT
# Localization
from scripts.ui import localization
-LANG = localization.LANG
+TEXT = localization.TEXT
#========================================== FUNCTIONS ========================================
# 左侧面板功能
@@ -439,15 +439,15 @@ def clean():
# 确认删除
result = cmds.confirmDialog(
- title=LANG.get("confirm_delete", "确认删除"),
- message=LANG.get("delete_lod_confirm", f"确定要删除{lod_name}吗?"),
- button=[LANG.get("yes", "是"), LANG.get("no", "否")],
- defaultButton=LANG.get("no", "否"),
- cancelButton=LANG.get("no", "否"),
- dismissString=LANG.get("no", "否")
+ title=TEXT("confirm_delete", "确认删除"),
+ message=TEXT("delete_lod_confirm", f"确定要删除{lod_name}吗?"),
+ button=[TEXT("yes", "是"), TEXT("no", "否")],
+ defaultButton=TEXT("no", "否"),
+ cancelButton=TEXT("no", "否"),
+ dismissString=TEXT("no", "否")
)
- if result == LANG.get("yes", "是"):
+ if result == TEXT("yes", "是"):
# 删除与该LOD相关的所有模型
nodes_to_delete = cmds.ls(f"{lod_name}_*")
if nodes_to_delete:
@@ -548,7 +548,7 @@ def separate_model():
# 获取当前选中的模型
selected_models = cmds.ls(selection=True, type="transform")
if not selected_models:
- cmds.warning(LANG.get("no_model_selected", "未选中模型"))
+ cmds.warning(TEXT("no_model_selected", "未选中模型"))
return False
# 对每个选中的模型进行分离
@@ -572,7 +572,7 @@ def fix_normals():
# 获取当前选中的模型
selected_models = cmds.ls(selection=True, type="transform")
if not selected_models:
- cmds.warning(LANG.get("no_model_selected", "未选中模型"))
+ cmds.warning(TEXT("no_model_selected", "未选中模型"))
return False
# 对每个选中的模型修复法线
@@ -626,7 +626,7 @@ def modify_topology():
# 获取当前选中的模型
selected_models = cmds.ls(selection=True, type="transform")
if not selected_models:
- cmds.warning(LANG.get("no_model_selected", "未选中模型"))
+ cmds.warning(TEXT("no_model_selected", "未选中模型"))
return False
# 切换到多边形编辑模式
@@ -649,7 +649,7 @@ def generate_face_components():
# 获取当前选中的模型
selected_models = cmds.ls(selection=True, type="transform")
if not selected_models:
- cmds.warning(LANG.get("no_model_selected", "未选中模型"))
+ cmds.warning(TEXT("no_model_selected", "未选中模型"))
return False
# 生成眉毛
@@ -676,7 +676,7 @@ def generate_uvs():
# 获取当前选中的模型
selected_models = cmds.ls(selection=True, type="transform")
if not selected_models:
- cmds.warning(LANG.get("no_model_selected", "未选中模型"))
+ cmds.warning(TEXT("no_model_selected", "未选中模型"))
return False
# 为每个选中的模型生成UV
diff --git a/scripts/utils/utils_rigging.py b/scripts/utils/utils_rigging.py
index a8e71e6..e490842 100644
--- a/scripts/utils/utils_rigging.py
+++ b/scripts/utils/utils_rigging.py
@@ -44,7 +44,7 @@ TOOL_WIDTH = config.TOOL_WIDTH
TOOL_HEIGHT = config.TOOL_HEIGHT
# Localization
from scripts.ui import localization
-LANG = localization.LANG
+TEXT = localization.TEXT
#========================================== GLOBALS ========================================
# 存储当前选中的关节和控制器信息
diff --git a/scripts/utils/utils_toolbar.py b/scripts/utils/utils_toolbar.py
index c975b1d..a30db88 100644
--- a/scripts/utils/utils_toolbar.py
+++ b/scripts/utils/utils_toolbar.py
@@ -39,10 +39,7 @@ TOOL_WIDTH = config.TOOL_WIDTH
TOOL_HEIGHT = config.TOOL_HEIGHT
# Localization
from scripts.ui import localization
-LANG = localization.LANG
-
-# 添加全局变量记录当前语言
-current_language = "zh_CN" # 默认使用中文
+TEXT = localization.TEXT
#========================================== FUNCTIONS ========================================
@@ -57,7 +54,7 @@ def save_dna():
fileFilter="DNA Files (*.dna);;All Files (*.*)",
dialogStyle=2,
fileMode=0,
- caption=LANG.get("save_dna", "保存DNA文件")
+ caption=TEXT("save_dna", "保存DNA文件")
)
if file_path and len(file_path) > 0:
@@ -77,7 +74,7 @@ def open_dna():
fileFilter="DNA Files (*.dna);;All Files (*.*)",
dialogStyle=2,
fileMode=1,
- caption=LANG.get("open_dna", "打开DNA文件")
+ caption=TEXT("open_dna", "打开DNA文件")
)
if file_path and len(file_path) > 0:
@@ -123,7 +120,7 @@ def import_skin():
fileFilter="Skin Files (*.skin);;XML Files (*.xml);;All Files (*.*)",
dialogStyle=2,
fileMode=1,
- caption=LANG.get("import_skin", "导入蒙皮")
+ caption=TEXT("import_skin", "导入蒙皮")
)
if file_path and len(file_path) > 0:
@@ -143,7 +140,7 @@ def export_skin():
fileFilter="Skin Files (*.skin);;XML Files (*.xml);;All Files (*.*)",
dialogStyle=2,
fileMode=0,
- caption=LANG.get("export_skin", "导出蒙皮")
+ caption=TEXT("export_skin", "导出蒙皮")
)
if file_path and len(file_path) > 0:
@@ -174,8 +171,8 @@ def show_help():
try:
# 打开帮助文档或显示帮助对话框
help_dialog = QtWidgets.QMessageBox()
- help_dialog.setWindowTitle(LANG.get("help_title", "帮助"))
- help_dialog.setText(LANG.get("help_message", "该插件是一个用于自定义MetaHuman的Maya插件。\n\n详细信息请参考文档。"))
+ help_dialog.setWindowTitle(TEXT("help_title", "帮助"))
+ help_dialog.setText(TEXT("help_message", "该插件是一个用于自定义MetaHuman的Maya插件。\n\n详细信息请参考文档。"))
help_dialog.setStandardButtons(QtWidgets.QMessageBox.Ok)
help_dialog.exec_()
except Exception as e:
@@ -302,10 +299,10 @@ def show_help():
webbrowser.open(config.TOOL_HELP_URL)
else:
cmds.confirmDialog(
- title=LANG.get("help", "帮助"),
- message=LANG.get("help_not_available", "帮助文档暂不可用"),
- button=[LANG.get("ok", "确定")],
- defaultButton=LANG.get("ok", "确定")
+ title=TEXT("help", "帮助"),
+ message=TEXT("help_not_available", "帮助文档暂不可用"),
+ button=[TEXT("ok", "确定")],
+ defaultButton=TEXT("ok", "确定")
)
except Exception as e:
print(f"显示帮助信息时出错: {e}")
@@ -360,15 +357,12 @@ def toggle_language():
"""
from scripts.ui import localization
import config
- from ui.Qt import QtWidgets
-
+ from scripts.ui.Qt import QtWidgets
+
# 使用localization模块来切换语言
new_language = localization.switch_language()
-
- # 更新配置
config.TOOL_LANG = new_language
-
- # 尝试更新已有窗口的语言,而不重启窗口
+
try:
# 查找主窗口
main_window = None
@@ -376,37 +370,33 @@ def toggle_language():
if widget.objectName() == f"{config.TOOL_NAME}MainWindow" and isinstance(widget, QtWidgets.QWidget):
main_window = widget
break
-
+
if main_window:
# 更新主窗口标题
main_window.setWindowTitle(f"{config.TOOL_NAME} {config.TOOL_VERSION}")
-
- # 获取各个UI实例并更新语言
- from scripts.ui import geometry, rigging, behaviour, definition, toolbar
-
- # 更新各个模块的UI
- if hasattr(geometry, 'GeometryUI') and geometry.GeometryUI.get_instance():
- geometry.GeometryUI.get_instance().update_language()
-
- if hasattr(rigging, 'RiggingUI') and rigging.RiggingUI.get_instance():
- rigging.RiggingUI.get_instance().update_language()
-
- if hasattr(behaviour, 'BehaviourUI') and behaviour.BehaviourUI.get_instance():
- behaviour.BehaviourUI.get_instance().update_language()
-
- if hasattr(definition, 'DefinitionUI') and definition.DefinitionUI.get_instance():
- definition.DefinitionUI.get_instance().update_language()
-
- # 更新工具栏
- if hasattr(toolbar, 'ToolbarUI') and hasattr(main_window, 'toolbar_ui'):
- main_window.toolbar_ui.update_language()
+
+ # 遍历主窗口的所有子控件,批量动态更新语言
+ for child in main_window.findChildren(QtWidgets.QWidget):
+ # 只要有update_language方法就调用
+ if hasattr(child, 'update_language') and callable(child.update_language):
+ try:
+ child.update_language()
+ except Exception as e:
+ print(f"更新语言失败: {child}: {e}")
# 更新功能按钮文字
if hasattr(main_window, 'function_buttons'):
for key, button in main_window.function_buttons.items():
- button.setText(localization.get_text(key))
+ button.setText(localization.TEXT(key))
print(f"语言已切换到: {new_language}")
+
+ # 切换语言后强制重载主窗口,保证所有UI和控件100%刷新
+ from scripts.Main import main
+ for widget in QtWidgets.QApplication.allWidgets():
+ if widget.objectName() == f"{config.TOOL_NAME}MainWindow" and isinstance(widget, QtWidgets.QWidget):
+ widget.close()
+ main()
return
except Exception as e:
print(f"动态更新语言失败,将重启窗口: {e}")