This commit is contained in:
2025-05-05 18:15:02 +08:00
parent 01c0ec760f
commit 46d93efb3c
11 changed files with 1728 additions and 1943 deletions

View File

@@ -10,459 +10,266 @@ Definition UI Module for Plugin
- 创建:创建混合变形,绑定蒙皮,取消蒙皮
- 工具:重新定位头部关节,重新定位身体关节,重新定位全身关节,快速创建预设
"""
#===================================== IMPORT MODULES =====================================
#========================================= IMPORT =========================================
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 FUNCTIONS ===================================
from scripts.utils import utils_definition as utils_definition
from scripts.ui import ui_utils
from scripts.utils import utils_definition
#========================================== 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
#========================================= LOCATION =======================================
from scripts.ui import localization
LANG = localization.LANG
#========================================== WIDGETS ==========================================
# 全局变量存储UI控件
definition_tabs = None
dna_elements = {}
definition_buttons = {}
class DefinitionUI(ui_utils.BaseUI):
"""
定义系统UI类 - 负责显示DNA定义编辑界面和基础操作
继承自BaseUI类实现DNA定义相关的UI功能
"""
#========================================== INIT ========================================
def __init__(self):
"""
初始化定义系统UI
创建主控件和布局,并连接信号和槽
"""
super(DefinitionUI, self).__init__()
# 创建主控件
self.main_widget = QtWidgets.QWidget()
self.main_widget.setObjectName("definitionMainWidget")
# 初始化UI
self.create_widgets()
self.create_layouts()
self.create_connections()
def set_button_icon(button, icon_name):
"""
设置按钮图标使用Maya默认图标
Args:
button: 要设置图标的按钮
icon_name: 图标文件名
"""
# 使用Maya内置图标
from maya import cmds
# 设置按钮图标使用Maya的图标
button.setIcon(QtGui.QIcon(":/{}".format(icon_name)))
button.setIconSize(QtCore.QSize(24, 24)) # 图标尺寸
print(f"成功设置按钮图标: {icon_name}")
# 注意:如果图标加载失败,我们会看到一个空图标,但不会引起错误
#========================================= WIDGET =======================================
def create_widgets(self):
"""
创建定义系统UI控件
包括按钮、标签、列表等
"""
# 标题标签
self.controls["title_label"] = QtWidgets.QLabel(LANG.get("definition_title", "DNA定义"))
self.controls["title_label"].setObjectName("definitionTitleLabel")
self.controls["title_label"].setAlignment(QtCore.Qt.AlignCenter)
# 创建主分割器
self.splitters["main_splitter"] = QtWidgets.QSplitter(QtCore.Qt.Horizontal)
self.splitters["main_splitter"].setObjectName("definitionMainSplitter")
# 左侧面板
self.controls["left_panel"] = QtWidgets.QWidget()
self.controls["left_panel"].setObjectName("definitionLeftPanel")
# 右侧面板
self.controls["right_panel"] = QtWidgets.QWidget()
self.controls["right_panel"].setObjectName("definitionRightPanel")
# 左侧面板控件
# LOD组
self.controls["lod_group"] = QtWidgets.QGroupBox(LANG.get("lod_group", "LOD"))
self.controls["lod_group"].setObjectName("lodGroup")
# LOD列表
self.controls["lod_list"] = QtWidgets.QListWidget()
self.controls["lod_list"].setObjectName("lodList")
# LOD刷新按钮
self.buttons["refresh_lod"] = QtWidgets.QPushButton(LANG.get("refresh", "刷新"))
self.buttons["refresh_lod"].setObjectName("refreshLodButton")
# Meshes组
self.controls["meshes_group"] = QtWidgets.QGroupBox(LANG.get("meshes_group", "几何体"))
self.controls["meshes_group"].setObjectName("meshesGroup")
# Meshes列表
self.controls["meshes_list"] = QtWidgets.QListWidget()
self.controls["meshes_list"].setObjectName("meshesList")
# Meshes刷新按钮
self.buttons["refresh_meshes"] = QtWidgets.QPushButton(LANG.get("refresh", "刷新"))
self.buttons["refresh_meshes"].setObjectName("refreshMeshesButton")
# Joints组
self.controls["joints_group"] = QtWidgets.QGroupBox(LANG.get("joints_group", "关节"))
self.controls["joints_group"].setObjectName("jointsGroup")
# Joints列表
self.controls["joints_list"] = QtWidgets.QListWidget()
self.controls["joints_list"].setObjectName("jointsList")
# Joints刷新按钮
self.buttons["refresh_joints"] = QtWidgets.QPushButton(LANG.get("refresh", "刷新"))
self.buttons["refresh_joints"].setObjectName("refreshJointsButton")
# 右侧面板控件
# 写入组
self.controls["write_group"] = QtWidgets.QGroupBox(LANG.get("write_group", "写入"))
self.controls["write_group"].setObjectName("writeGroup")
# 写入按钮
self.buttons["write_joint_default"] = QtWidgets.QPushButton(LANG.get("write_joint_default", "写入关节默认位置"))
self.buttons["write_geometry"] = QtWidgets.QPushButton(LANG.get("write_geometry", "写入几何体"))
self.buttons["write_skinning"] = QtWidgets.QPushButton(LANG.get("write_skinning", "写入蒙皮"))
self.buttons["write_blendshape"] = QtWidgets.QPushButton(LANG.get("write_blendshape", "写入混合变形目标"))
# 创建组
self.controls["create_group"] = QtWidgets.QGroupBox(LANG.get("create_group", "创建"))
self.controls["create_group"].setObjectName("createGroup")
# 创建按钮
self.buttons["create_blendshape"] = QtWidgets.QPushButton(LANG.get("create_blendshape", "创建混合变形"))
self.buttons["bind_skin"] = QtWidgets.QPushButton(LANG.get("bind_skin", "绑定蒙皮"))
self.buttons["unbind_skin"] = QtWidgets.QPushButton(LANG.get("unbind_skin", "取消蒙皮"))
# 工具组
self.controls["tools_group"] = QtWidgets.QGroupBox(LANG.get("tools_group", "工具"))
self.controls["tools_group"].setObjectName("toolsGroup")
# 工具按钮
self.buttons["reposition_head_joints"] = QtWidgets.QPushButton(LANG.get("reposition_head_joints", "重新定位头部关节"))
self.buttons["reposition_body_joints"] = QtWidgets.QPushButton(LANG.get("reposition_body_joints", "重新定位身体关节"))
self.buttons["reposition_all_joints"] = QtWidgets.QPushButton(LANG.get("reposition_all_joints", "重新定位全身关节"))
self.buttons["quick_preset"] = QtWidgets.QPushButton(LANG.get("quick_preset", "快速创建预设"))
def widgets():
"""
创建定义系统UI控件
"""
global definition_tabs, dna_elements, definition_buttons
# 创建子标签页
definition_tabs = QtWidgets.QTabWidget()
# 创建各类元素列表
dna_elements["lod_list"] = QtWidgets.QListWidget()
dna_elements["lod_list"].setObjectName("LodList")
dna_elements["mesh_list"] = QtWidgets.QListWidget()
dna_elements["mesh_list"].setObjectName("MeshList")
dna_elements["joint_list"] = QtWidgets.QListWidget()
dna_elements["joint_list"].setObjectName("JointList")
dna_elements["blendshape_list"] = QtWidgets.QListWidget()
dna_elements["blendshape_list"].setObjectName("BlendshapeList")
dna_elements["animmap_list"] = QtWidgets.QListWidget()
dna_elements["animmap_list"].setObjectName("AnimatedMapList")
# 创建元素信息面板
dna_elements["element_info"] = QtWidgets.QTextEdit()
dna_elements["element_info"].setReadOnly(True)
dna_elements["element_info"].setObjectName("ElementInfo")
# 创建列表标题标签
dna_elements["lod_label"] = QtWidgets.QLabel("LODs [000]")
dna_elements["mesh_label"] = QtWidgets.QLabel("Meshes [000]")
dna_elements["joint_label"] = QtWidgets.QLabel("Joints [000]")
dna_elements["blendshape_label"] = QtWidgets.QLabel("BlendShapes [000]")
dna_elements["animmap_label"] = QtWidgets.QLabel("AnimatedMap [000]")
# 创建刷新按钮
dna_elements["refresh_lod"] = QtWidgets.QPushButton("刷新")
dna_elements["refresh_lod"].setObjectName("RefreshButton")
dna_elements["refresh_lod"].setFixedWidth(60)
dna_elements["refresh_mesh"] = QtWidgets.QPushButton("刷新")
dna_elements["refresh_mesh"].setObjectName("RefreshButton")
dna_elements["refresh_mesh"].setFixedWidth(60)
dna_elements["refresh_joint"] = QtWidgets.QPushButton("刷新")
dna_elements["refresh_joint"].setObjectName("RefreshButton")
dna_elements["refresh_joint"].setFixedWidth(60)
dna_elements["refresh_blendshape"] = QtWidgets.QPushButton("刷新")
dna_elements["refresh_blendshape"].setObjectName("RefreshButton")
dna_elements["refresh_blendshape"].setFixedWidth(60)
dna_elements["refresh_animmap"] = QtWidgets.QPushButton("刷新")
dna_elements["refresh_animmap"].setObjectName("RefreshButton")
dna_elements["refresh_animmap"].setFixedWidth(60)
# 创建LOD和Meshes特殊按钮
dna_elements["define_lod_joint"] = QtWidgets.QPushButton("定义LOD关节")
set_button_icon(dna_elements["define_lod_joint"], "layerEditor.png")
dna_elements["define_lod_joint"].setMinimumHeight(28)
dna_elements["define_lod_joint"].setStyleSheet("text-align: left; padding-left: 30px;")
dna_elements["define_lod_joint"].setToolTip("定义LOD关节")
dna_elements["create_geometry"] = QtWidgets.QPushButton("创建几何体")
set_button_icon(dna_elements["create_geometry"], "polyCube.png")
dna_elements["create_geometry"].setMinimumHeight(28)
dna_elements["create_geometry"].setStyleSheet("text-align: left; padding-left: 30px;")
dna_elements["create_geometry"].setToolTip("创建几何体")
# 功能按钮
# 写入组按钮
definition_buttons["write_joint_defaults"] = QtWidgets.QPushButton("写入关节默认位置")
set_button_icon(definition_buttons["write_joint_defaults"], "HIKCharacterToolBodyPart.png")
definition_buttons["write_geometry"] = QtWidgets.QPushButton("写入几何体")
set_button_icon(definition_buttons["write_geometry"], "polyCube.png")
definition_buttons["write_skinning"] = QtWidgets.QPushButton("写入蒙皮权重")
set_button_icon(definition_buttons["write_skinning"], "paintSkinWeights.png")
definition_buttons["write_blendshapes"] = QtWidgets.QPushButton("写入混合变形目标")
set_button_icon(definition_buttons["write_blendshapes"], "blendShape.png")
# 创建组按钮
definition_buttons["create_blendshapes"] = QtWidgets.QPushButton("创建混合变形")
set_button_icon(definition_buttons["create_blendshapes"], "blendShapeEditor.png")
definition_buttons["bind_skin"] = QtWidgets.QPushButton("绑定蒙皮")
set_button_icon(definition_buttons["bind_skin"], "smoothSkin.png")
definition_buttons["unbind_skin"] = QtWidgets.QPushButton("取消蒙皮")
set_button_icon(definition_buttons["unbind_skin"], "detachSkin.png")
# 工具组按钮
definition_buttons["reposition_head"] = QtWidgets.QPushButton("重新定位头部关节")
set_button_icon(definition_buttons["reposition_head"], "HIKCharacterToolSkeleton.png")
definition_buttons["reposition_body"] = QtWidgets.QPushButton("重新定位身体关节")
set_button_icon(definition_buttons["reposition_body"], "HIKCharacterToolSkeleton.png")
definition_buttons["reposition_all"] = QtWidgets.QPushButton("重新定位全身关节")
set_button_icon(definition_buttons["reposition_all"], "HIKCharacterToolSkeleton.png")
definition_buttons["quick_preset"] = QtWidgets.QPushButton("快速创建预设")
set_button_icon(definition_buttons["quick_preset"], "QR_QuickRigTool.png")
# 设置按钮样式
for button in definition_buttons.values():
button.setMinimumHeight(28)
# 设置按钮文本对齐方式,使图标在左侧,文本在右侧
button.setStyleSheet("text-align: left; padding-left: 30px;")
# 设置工具提示与按钮文本相同
button.setToolTip(button.text())
#========================================= LAYOUT =======================================
def create_layouts(self):
"""
创建定义系统UI布局
组织控件的排列和层次结构
"""
# 主布局
self.layouts["main_layout"] = QtWidgets.QVBoxLayout(self.main_widget)
self.layouts["main_layout"].setContentsMargins(5, 5, 5, 5)
self.layouts["main_layout"].setSpacing(5)
# 添加标题标签
self.layouts["main_layout"].addWidget(self.controls["title_label"])
# 添加主分割器
self.layouts["main_layout"].addWidget(self.splitters["main_splitter"])
# 将左右面板添加到主分割器
self.splitters["main_splitter"].addWidget(self.controls["left_panel"])
self.splitters["main_splitter"].addWidget(self.controls["right_panel"])
# 左侧面板布局
self.layouts["left_layout"] = QtWidgets.QVBoxLayout(self.controls["left_panel"])
self.layouts["left_layout"].setContentsMargins(5, 5, 5, 5)
self.layouts["left_layout"].setSpacing(5)
# LOD组布局
self.layouts["lod_layout"] = QtWidgets.QVBoxLayout(self.controls["lod_group"])
self.layouts["lod_layout"].addWidget(self.controls["lod_list"])
self.layouts["lod_layout"].addWidget(self.buttons["refresh_lod"])
# Meshes组布局
self.layouts["meshes_layout"] = QtWidgets.QVBoxLayout(self.controls["meshes_group"])
self.layouts["meshes_layout"].addWidget(self.controls["meshes_list"])
self.layouts["meshes_layout"].addWidget(self.buttons["refresh_meshes"])
# Joints组布局
self.layouts["joints_layout"] = QtWidgets.QVBoxLayout(self.controls["joints_group"])
self.layouts["joints_layout"].addWidget(self.controls["joints_list"])
self.layouts["joints_layout"].addWidget(self.buttons["refresh_joints"])
# 添加组到左侧面板布局
self.layouts["left_layout"].addWidget(self.controls["lod_group"])
self.layouts["left_layout"].addWidget(self.controls["meshes_group"])
self.layouts["left_layout"].addWidget(self.controls["joints_group"])
self.layouts["left_layout"].addStretch()
# 右侧面板布局
self.layouts["right_layout"] = QtWidgets.QVBoxLayout(self.controls["right_panel"])
self.layouts["right_layout"].setContentsMargins(5, 5, 5, 5)
self.layouts["right_layout"].setSpacing(5)
# 写入组布局
self.layouts["write_layout"] = QtWidgets.QVBoxLayout(self.controls["write_group"])
self.layouts["write_layout"].addWidget(self.buttons["write_joint_default"])
self.layouts["write_layout"].addWidget(self.buttons["write_geometry"])
self.layouts["write_layout"].addWidget(self.buttons["write_skinning"])
self.layouts["write_layout"].addWidget(self.buttons["write_blendshape"])
# 创建组布局
self.layouts["create_layout"] = QtWidgets.QVBoxLayout(self.controls["create_group"])
self.layouts["create_layout"].addWidget(self.buttons["create_blendshape"])
self.layouts["create_layout"].addWidget(self.buttons["bind_skin"])
self.layouts["create_layout"].addWidget(self.buttons["unbind_skin"])
# 工具组布局
self.layouts["tools_layout"] = QtWidgets.QVBoxLayout(self.controls["tools_group"])
self.layouts["tools_layout"].addWidget(self.buttons["reposition_head_joints"])
self.layouts["tools_layout"].addWidget(self.buttons["reposition_body_joints"])
self.layouts["tools_layout"].addWidget(self.buttons["reposition_all_joints"])
self.layouts["tools_layout"].addWidget(self.buttons["quick_preset"])
# 添加组到右侧面板布局
self.layouts["right_layout"].addWidget(self.controls["write_group"])
self.layouts["right_layout"].addWidget(self.controls["create_group"])
self.layouts["right_layout"].addWidget(self.controls["tools_group"])
self.layouts["right_layout"].addStretch()
# 创建分割器大小处理器
self.resize_handlers["main_splitter"] = ui_utils.SplitterResizeHandler(
self.main_widget, self.splitters["main_splitter"], is_horizontal=True
)
#========================================== LAYOUTS ==========================================
def layouts(parent_tab=None):
"""
创建定义系统UI布局
Args:
parent_tab: 父容器控件由Main.py传入
"""
# 获取父容器在Main.py中创建的definition_tab
if not parent_tab:
parent_tab = ui_utils.get_parent_widget("definition_tab")
if not parent_tab:
print("无法获取父容器,布局创建失败")
return
# 创建主布局
main_layout = parent_tab.layout()
if not main_layout:
print("父容器没有布局,布局创建失败")
return
# 创建主分割控件 - 水平分割
main_splitter = QtWidgets.QSplitter(QtCore.Qt.Horizontal)
# 创建左侧区域 - 垂直分割
left_splitter = QtWidgets.QSplitter(QtCore.Qt.Vertical)
# 创建LOD区域
lod_widget = QtWidgets.QWidget()
lod_layout = QtWidgets.QVBoxLayout(lod_widget)
lod_layout.setContentsMargins(4, 4, 4, 4)
lod_layout.setSpacing(4)
# LOD标题栏
lod_header = QtWidgets.QWidget()
lod_header_layout = QtWidgets.QHBoxLayout(lod_header)
lod_header_layout.setContentsMargins(0, 0, 0, 0)
lod_header_layout.addWidget(dna_elements["lod_label"])
lod_header_layout.addStretch()
lod_header_layout.addWidget(dna_elements["refresh_lod"])
lod_layout.addWidget(lod_header)
lod_layout.addWidget(dna_elements["lod_list"])
lod_layout.addWidget(dna_elements["define_lod_joint"])
# 创建Meshes区域
mesh_widget = QtWidgets.QWidget()
mesh_layout = QtWidgets.QVBoxLayout(mesh_widget)
mesh_layout.setContentsMargins(4, 4, 4, 4)
mesh_layout.setSpacing(4)
# Meshes标题栏
mesh_header = QtWidgets.QWidget()
mesh_header_layout = QtWidgets.QHBoxLayout(mesh_header)
mesh_header_layout.setContentsMargins(0, 0, 0, 0)
mesh_header_layout.addWidget(dna_elements["mesh_label"])
mesh_header_layout.addStretch()
mesh_header_layout.addWidget(dna_elements["refresh_mesh"])
mesh_layout.addWidget(mesh_header)
mesh_layout.addWidget(dna_elements["mesh_list"])
mesh_layout.addWidget(dna_elements["create_geometry"])
# 添加到左侧垂直分割控件
left_splitter.addWidget(lod_widget)
left_splitter.addWidget(mesh_widget)
# 创建右侧区域 - 垂直分割
right_splitter = QtWidgets.QSplitter(QtCore.Qt.Vertical)
# 创建右上区域 - Joints
right_top_widget = QtWidgets.QWidget()
right_top_layout = QtWidgets.QVBoxLayout(right_top_widget)
right_top_layout.setContentsMargins(4, 4, 4, 4)
right_top_layout.setSpacing(4)
# Joints标题栏
joint_header = QtWidgets.QWidget()
joint_header_layout = QtWidgets.QHBoxLayout(joint_header)
joint_header_layout.setContentsMargins(0, 0, 0, 0)
joint_header_layout.addWidget(dna_elements["joint_label"])
joint_header_layout.addStretch()
joint_header_layout.addWidget(dna_elements["refresh_joint"])
right_top_layout.addWidget(joint_header)
right_top_layout.addWidget(dna_elements["joint_list"])
# 创建右中区域 - BlendShapes
right_middle_widget = QtWidgets.QWidget()
right_middle_layout = QtWidgets.QVBoxLayout(right_middle_widget)
right_middle_layout.setContentsMargins(4, 4, 4, 4)
right_middle_layout.setSpacing(4)
# BlendShapes标题栏
blendshape_header = QtWidgets.QWidget()
blendshape_header_layout = QtWidgets.QHBoxLayout(blendshape_header)
blendshape_header_layout.setContentsMargins(0, 0, 0, 0)
blendshape_header_layout.addWidget(dna_elements["blendshape_label"])
blendshape_header_layout.addStretch()
blendshape_header_layout.addWidget(dna_elements["refresh_blendshape"])
right_middle_layout.addWidget(blendshape_header)
right_middle_layout.addWidget(dna_elements["blendshape_list"])
# 创建右下区域 - AnimatedMap
right_bottom_widget = QtWidgets.QWidget()
right_bottom_layout = QtWidgets.QVBoxLayout(right_bottom_widget)
right_bottom_layout.setContentsMargins(4, 4, 4, 4)
right_bottom_layout.setSpacing(4)
# AnimatedMap标题栏
animmap_header = QtWidgets.QWidget()
animmap_header_layout = QtWidgets.QHBoxLayout(animmap_header)
animmap_header_layout.setContentsMargins(0, 0, 0, 0)
animmap_header_layout.addWidget(dna_elements["animmap_label"])
animmap_header_layout.addStretch()
animmap_header_layout.addWidget(dna_elements["refresh_animmap"])
right_bottom_layout.addWidget(animmap_header)
right_bottom_layout.addWidget(dna_elements["animmap_list"])
# 添加到右侧分割控件
right_splitter.addWidget(right_top_widget)
right_splitter.addWidget(right_middle_widget)
right_splitter.addWidget(right_bottom_widget)
# 设置右侧分割控件比例
right_splitter.setSizes([200, 200, 200])
# 设置左侧分割控件比例 - 使其均等
left_splitter.setSizes([300, 300])
# 设置左侧分割控件的伸缩因子,使两个模块均等分配空间
left_splitter.setStretchFactor(0, 1) # LOD区域伸缩因子为1
left_splitter.setStretchFactor(1, 1) # Meshes区域伸缩因子为1
# 添加到主分割控件
main_splitter.addWidget(left_splitter)
main_splitter.addWidget(right_splitter)
# 设置主分割控件比例 - 左右宽度相等
main_splitter.setSizes([500, 500])
# 设置分割控件的伸缩因子,使其根据窗口大小均等分配空间
main_splitter.setStretchFactor(0, 1) # 左侧伸缩因子为1
main_splitter.setStretchFactor(1, 1) # 右侧伸缩因子为1
# 创建底部功能区域
bottom_widget = QtWidgets.QWidget()
bottom_layout = QtWidgets.QHBoxLayout(bottom_widget)
bottom_layout.setContentsMargins(4, 4, 4, 4)
# 创建功能分组
write_group = QtWidgets.QGroupBox("写入")
write_layout = QtWidgets.QVBoxLayout(write_group)
write_layout.setAlignment(QtCore.Qt.AlignTop) # 设置向顶部对齐
write_layout.setContentsMargins(4, 8, 4, 4) # 减小内边距
write_layout.setSpacing(4) # 减小间距
write_layout.addWidget(definition_buttons["write_joint_defaults"])
write_layout.addWidget(definition_buttons["write_geometry"])
write_layout.addWidget(definition_buttons["write_skinning"])
write_layout.addWidget(definition_buttons["write_blendshapes"])
write_layout.addStretch() # 添加弹性空间,使按钮向顶部对齐
create_group = QtWidgets.QGroupBox("创建")
create_layout = QtWidgets.QVBoxLayout(create_group)
create_layout.setAlignment(QtCore.Qt.AlignTop) # 设置向顶部对齐
create_layout.setContentsMargins(4, 8, 4, 4) # 减小内边距
create_layout.setSpacing(4) # 减小间距
create_layout.addWidget(definition_buttons["create_blendshapes"])
create_layout.addWidget(definition_buttons["bind_skin"])
create_layout.addWidget(definition_buttons["unbind_skin"])
create_layout.addStretch() # 添加弹性空间,使按钮向顶部对齐
tools_group = QtWidgets.QGroupBox("工具")
tools_layout = QtWidgets.QVBoxLayout(tools_group)
tools_layout.setAlignment(QtCore.Qt.AlignTop) # 设置向顶部对齐
tools_layout.setContentsMargins(4, 8, 4, 4) # 减小内边距
tools_layout.setSpacing(4) # 减小间距
tools_layout.addWidget(definition_buttons["reposition_head"])
tools_layout.addWidget(definition_buttons["reposition_body"])
tools_layout.addWidget(definition_buttons["reposition_all"])
tools_layout.addWidget(definition_buttons["quick_preset"])
tools_layout.addStretch() # 添加弹性空间,使按钮向顶部对齐
# 添加到底部布局
bottom_layout.addWidget(write_group)
bottom_layout.addWidget(create_group)
bottom_layout.addWidget(tools_group)
# 创建主容器
main_container = QtWidgets.QWidget()
container_layout = QtWidgets.QVBoxLayout(main_container)
container_layout.setContentsMargins(0, 0, 0, 0)
container_layout.setSpacing(4)
container_layout.addWidget(main_splitter, 1)
container_layout.addWidget(bottom_widget, 0)
# 添加到主布局
main_layout.addWidget(main_container)
#========================================== CONNECTIONS ==========================================
def connections():
"""
连接定义系统UI信号和槽
"""
# 连接功能按钮点击事件
definition_buttons["write_joint_defaults"].clicked.connect(lambda: print("写入关节默认位置功能待实现"))
definition_buttons["write_geometry"].clicked.connect(lambda: print("写入几何体功能待实现"))
definition_buttons["write_skinning"].clicked.connect(lambda: print("写入蒙皮功能待实现"))
definition_buttons["write_blendshapes"].clicked.connect(lambda: print("写入混合变形目标功能待实现"))
definition_buttons["create_blendshapes"].clicked.connect(lambda: print("创建混合变形功能待实现"))
definition_buttons["bind_skin"].clicked.connect(lambda: print("绑定蒙皮功能待实现"))
definition_buttons["unbind_skin"].clicked.connect(lambda: print("取消蒙皮功能待实现"))
definition_buttons["reposition_head"].clicked.connect(lambda: print("重新定位头部关节功能待实现"))
definition_buttons["reposition_body"].clicked.connect(lambda: print("重新定位身体关节功能待实现"))
definition_buttons["reposition_all"].clicked.connect(lambda: print("重新定位全身关节功能待实现"))
definition_buttons["quick_preset"].clicked.connect(lambda: print("快速创建预设功能待实现"))
# 连接列表选择事件
for key, widget in dna_elements.items():
if isinstance(widget, QtWidgets.QListWidget):
widget.itemSelectionChanged.connect(lambda k=key: on_list_selection_changed(k))
widget.itemDoubleClicked.connect(lambda item, k=key: on_list_item_double_clicked(item, k))
# 连接刷新按钮点击事件
dna_elements["refresh_lod"].clicked.connect(lambda: refresh_list("lod_list"))
dna_elements["refresh_mesh"].clicked.connect(lambda: refresh_list("mesh_list"))
dna_elements["refresh_joint"].clicked.connect(lambda: refresh_list("joint_list"))
dna_elements["refresh_blendshape"].clicked.connect(lambda: refresh_list("blendshape_list"))
dna_elements["refresh_animmap"].clicked.connect(lambda: refresh_list("animmap_list"))
# 连接LOD和Meshes特殊按钮点击事件
dna_elements["define_lod_joint"].clicked.connect(lambda: print("定义LOD关节功能待实现"))
dna_elements["create_geometry"].clicked.connect(lambda: print("创建几何体功能待实现"))
# 列表选择变化处理函数
def on_list_selection_changed(list_key):
"""
处理列表选择变化事件
Args:
list_key: 列表键名
"""
selected_items = dna_elements[list_key].selectedItems()
if selected_items:
item = selected_items[0]
info_text = f"选中的{list_key.split('_')[0]}: {item.text()}\n"
info_text += f"\n属性信息将在此显示"
dna_elements["element_info"].setText(info_text)
print(f"{list_key} 选中项: {item.text()}")
# 列表项双击处理函数
def on_list_item_double_clicked(item, list_key):
"""
处理列表项双击事件
Args:
item: 被双击的列表项
list_key: 列表键名
"""
print(f"{list_key} 双击项: {item.text()}")
# 刷新列表函数
def refresh_list(list_key):
"""
刷新指定列表
Args:
list_key: 要刷新的列表键名
"""
list_widget = dna_elements[list_key]
list_widget.clear()
# 模拟数据加载
test_data = {
"lod_list": ["LOD_0", "LOD_1", "LOD_2"],
"mesh_list": ["Head", "Body", "Eyes", "Teeth", "Tongue"],
"joint_list": ["Head_Joint", "Neck_Joint", "Spine_Joint", "Arm_L_Joint", "Arm_R_Joint"],
"blendshape_list": ["Smile", "Frown", "Blink", "Jaw_Open", "Brow_Raise"],
"animmap_list": ["FaceMap_01", "BodyMap_01", "ExpressionMap_01"]
}
# 添加测试数据到列表
if list_key in test_data:
for item in test_data[list_key]:
list_widget.addItem(item)
# 更新对应标签的计数
label_key = list_key.replace("list", "label")
if label_key in dna_elements:
count = list_widget.count()
label_text = f"{label_key.split('_')[0].capitalize()}s [{count:03d}]"
dna_elements[label_key].setText(label_text)
print(f"刷新{list_key}完成")
#===================================== PLACEHOLDER FUNCTION ===================================
def definition_temp_function():
utils_definition.definition_temp_utils_function
#======================================= CONNECTION =====================================
def create_connections(self):
"""
连接信号和槽
设置UI控件的交互行为
"""
# 刷新按钮连接
self.buttons["refresh_lod"].clicked.connect(utils_definition.definition_temp_utils_function)
self.buttons["refresh_meshes"].clicked.connect(utils_definition.definition_temp_utils_function)
self.buttons["refresh_joints"].clicked.connect(utils_definition.definition_temp_utils_function)
# 写入按钮连接
self.buttons["write_joint_default"].clicked.connect(utils_definition.definition_temp_utils_function)
self.buttons["write_geometry"].clicked.connect(utils_definition.definition_temp_utils_function)
self.buttons["write_skinning"].clicked.connect(utils_definition.definition_temp_utils_function)
self.buttons["write_blendshape"].clicked.connect(utils_definition.definition_temp_utils_function)
# 创建按钮连接
self.buttons["create_blendshape"].clicked.connect(utils_definition.definition_temp_utils_function)
self.buttons["bind_skin"].clicked.connect(utils_definition.definition_temp_utils_function)
self.buttons["unbind_skin"].clicked.connect(utils_definition.definition_temp_utils_function)
# 工具按钮连接
self.buttons["reposition_head_joints"].clicked.connect(utils_definition.definition_temp_utils_function)
self.buttons["reposition_body_joints"].clicked.connect(utils_definition.definition_temp_utils_function)
self.buttons["reposition_all_joints"].clicked.connect(utils_definition.definition_temp_utils_function)
self.buttons["quick_preset"].clicked.connect(utils_definition.definition_temp_utils_function)