This commit is contained in:
2025-05-07 01:31:21 +08:00
parent d27ef50341
commit 27240530b6
18 changed files with 2033 additions and 1160 deletions

View File

@@ -53,6 +53,8 @@ ASSETS_PATH = config.ASSETS_PATH
DNA_FILE_PATH = config.DNA_FILE_PATH
DNA_IMG_PATH = config.DNA_IMG_PATH
TOOL_COMMAND_ICON = config.TOOL_COMMAND_ICON
TOOL_WIDTH = config.TOOL_WIDTH
TOOL_HEIGHT = config.TOOL_HEIGHT
#========================================= LOCATION =======================================
from scripts.ui import localization
LANG = localization.LANG
@@ -62,47 +64,83 @@ class BehaviourUI(ui_utils.BaseUI):
行为系统UI类 - 负责显示角色行为编辑界面和基础操作
继承自BaseUI类实现行为系统相关的UI功能
"""
#========================================== INIT ========================================
def __init__(self):
# 类变量,存储单例实例
_instance = None
@classmethod
def get_instance(cls):
"""
获取BehaviourUI的单例实例
Returns:
BehaviourUI: 单例实例如果不存在则返回None
"""
return cls._instance
def __init__(self, parent=None):
"""
初始化行为系统UI
创建主控件和布局,并连接信号和槽
"""
super(BehaviourUI, self).__init__()
# 创建主控件
self.main_widget = QtWidgets.QWidget()
super(BehaviourUI, self).__init__() # 不传递parent参数给BaseUI
self.main_widget = QtWidgets.QWidget(parent) # 在创建main_widget时传递parent
self.main_widget.setObjectName("behaviourMainWidget")
# 初始化UI
# 设置单例实例
BehaviourUI._instance = self
# 初始化控件、布局和按钮字典
self.controls = {}
self.layouts = {}
self.buttons = {}
self.splitters = {}
# 创建UI组件
self.create_widgets()
self.create_layouts()
self.create_connections()
#========================================= WIDGET =======================================
# 在创建完所有布局后,设置分割器的初始大小和属性
# 使用ui_utils中的函数来设置分割器大小
ui_utils.setup_splitter(self, "main_splitter", [1, 1])
# 设置分割器所有子元素的最小尺寸为0确保可以自由调整
ui_utils.set_splitter_children_minimum_size(self, recursive=True)
# 设置所有控件的最小尺寸为0确保分割器可以自由移动
ui_utils.set_all_controls_minimum_size(self)
# 使用ui_utils中的函数强制设置均等大小
ui_utils.force_equal_splitter_sizes(self)
def create_widgets(self):
"""
创建行为系统UI控件
包括按钮、标签、列表
包括标题标签、搜索框、控制列表、滑块
"""
# 标题标签 - 使用HTML格式化标题
title_text = f"<h4 style='margin:0;padding:5px;'>{LANG.get('behaviour_title', '行为')}</h4>"
self.controls["title_label"] = QtWidgets.QLabel(title_text)
# 标题标签
self.controls["title_label"] = QtWidgets.QLabel(LANG.get("behaviour_title", "行为系统"))
self.controls["title_label"].setObjectName("behaviourTitleLabel")
self.controls["title_label"].setAlignment(QtCore.Qt.AlignCenter)
self.controls["title_label"].setMaximumHeight(30) # 限制标题高度
self.controls["title_label"].setStyleSheet("font-size: 14px; font-weight: bold; padding: 5px;")
# 左侧面板
# 主分割器
self.splitters["main_splitter"] = QtWidgets.QSplitter(QtCore.Qt.Horizontal)
self.splitters["main_splitter"].setObjectName("behaviourMainSplitter")
self.splitters["main_splitter"].setHandleWidth(6) # 设置分割器手柄宽度
self.splitters["main_splitter"].setChildrenCollapsible(False) # 禁止子部件折叠
self.splitters["main_splitter"].setOpaqueResize(True) # 实时显示调整效果,更丝滑
# 左侧面板 - Raw Control
self.controls["left_panel"] = QtWidgets.QWidget()
self.controls["left_panel"].setObjectName("behaviourLeftPanel")
self.controls["left_panel"].setMinimumWidth(0)
self.controls["left_panel"].setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
# 右侧面板
# 右侧面板 - BlendShapes
self.controls["right_panel"] = QtWidgets.QWidget()
self.controls["right_panel"].setObjectName("behaviourRightPanel")
# 左侧面板控件 - Raw Control
self.controls["raw_control_group"] = QtWidgets.QGroupBox("Raw Control [000]")
self.controls["raw_control_group"].setObjectName("rawControlGroup")
self.controls["right_panel"].setMinimumWidth(0)
self.controls["right_panel"].setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
# 搜索框
self.controls["search_input"] = QtWidgets.QLineEdit()
@@ -112,15 +150,45 @@ class BehaviourUI(ui_utils.BaseUI):
# 控制列表
self.controls["control_list"] = QtWidgets.QListWidget()
self.controls["control_list"].setObjectName("controlList")
self.controls["control_list"].setMinimumWidth(0) # 设置最小宽度为零
# 底部滑块和按钮
self.controls["bottom_slider"] = QtWidgets.QSlider(QtCore.Qt.Horizontal)
self.controls["bottom_slider"].setObjectName("bottomSlider")
self.controls["bottom_slider"].setMinimum(0)
self.controls["bottom_slider"].setMaximum(100)
self.controls["bottom_slider"].setValue(10)
# 底部滑块
self.controls["raw_slider"] = QtWidgets.QSlider(QtCore.Qt.Horizontal)
self.controls["raw_slider"].setObjectName("rawSlider")
self.controls["raw_slider"].setMinimum(0)
self.controls["raw_slider"].setMaximum(100)
self.controls["raw_slider"].setValue(0)
self.controls["raw_slider"].setFixedHeight(20)
# 创建滑块布局,包含数值显示和滑块
self.layouts["raw_slider_layout"] = QtWidgets.QHBoxLayout()
self.layouts["raw_slider_layout"].setContentsMargins(0, 0, 0, 0)
self.layouts["raw_slider_layout"].setSpacing(2)
# 添加数值显示标签
self.controls["raw_slider_value"] = QtWidgets.QLabel("0.000")
self.controls["raw_slider_value"].setObjectName("rawSliderValue")
self.controls["raw_slider_value"].setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
self.controls["raw_slider_value"].setFixedWidth(40)
self.layouts["raw_slider_layout"].addWidget(self.controls["raw_slider_value"])
# 添加滑块
self.layouts["raw_slider_layout"].addWidget(self.controls["raw_slider"])
# 添加"All"勾选框和标签
self.controls["raw_slider_all_check"] = QtWidgets.QCheckBox("All")
self.controls["raw_slider_all_check"].setObjectName("rawSliderAllCheck")
self.layouts["raw_slider_layout"].addWidget(self.controls["raw_slider_all_check"])
# 页码按钮
self.buttons["prev_page"] = QtWidgets.QPushButton("上一页")
self.buttons["prev_page"].setObjectName("prevPageButton")
self.buttons["prev_page"].setIcon(ui_utils.get_icon("arrowLeft.png"))
self.buttons["next_page"] = QtWidgets.QPushButton("下一页")
self.buttons["next_page"].setObjectName("nextPageButton")
self.buttons["next_page"].setIcon(ui_utils.get_icon("arrowRight.png"))
self.buttons["page_all"] = QtWidgets.QPushButton("All")
self.buttons["page_all"].setObjectName("pageAllButton")
self.buttons["page_all"].setCheckable(True)
@@ -146,119 +214,204 @@ class BehaviourUI(ui_utils.BaseUI):
self.buttons["page_6"].setObjectName("page6Button")
self.buttons["page_6"].setCheckable(True)
# 左下角按钮
self.buttons["range_minus"] = QtWidgets.QPushButton("-")
self.buttons["range_minus"].setObjectName("rangeMinusButton")
self.buttons["range_plus"] = QtWidgets.QPushButton("+")
# 左下角Range按钮
self.buttons["range_plus"] = QtWidgets.QPushButton("Range +")
self.buttons["range_plus"].setObjectName("rangePlusButton")
self.buttons["range_plus"].setIcon(ui_utils.get_icon("behaviour.png"))
self.buttons["range_minus"] = QtWidgets.QPushButton("Range -")
self.buttons["range_minus"].setObjectName("rangeMinusButton")
self.buttons["range_minus"].setIcon(ui_utils.get_icon("behaviour.png"))
# 右侧面板控件 - Related BlendShapes
self.controls["blendshapes_group"] = QtWidgets.QGroupBox("Related BlendShapes [000]")
self.controls["blendshapes_group"].setObjectName("blendshapesGroup")
self.controls["blendshapes_group"].setMinimumWidth(0) # 设置最小宽度为零
self.controls["blendshapes_group"].setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
# BlendShapes列表
self.controls["blendshapes_list"] = QtWidgets.QListWidget()
self.controls["blendshapes_list"].setObjectName("blendshapesList")
self.controls["blendshapes_list"].setMinimumWidth(0) # 设置最小宽度为零
self.controls["blendshapes_list"].setMinimumHeight(100) # 设置最小高度,确保列表可见
self.controls["blendshapes_list"].setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
# 底部滑块和按钮
# 底部滑块
self.controls["bs_slider"] = QtWidgets.QSlider(QtCore.Qt.Horizontal)
self.controls["bs_slider"].setObjectName("bsSlider")
self.controls["bs_slider"].setMinimum(0)
self.controls["bs_slider"].setMaximum(100)
self.controls["bs_slider"].setValue(0)
# 创建BS滑块布局包含数值显示和滑块
self.layouts["bs_slider_layout"] = QtWidgets.QHBoxLayout()
self.layouts["bs_slider_layout"].setContentsMargins(0, 0, 0, 0)
self.layouts["bs_slider_layout"].setSpacing(2)
# 添加数值显示标签
self.controls["bs_slider_value"] = QtWidgets.QLabel("0.000")
self.controls["bs_slider_value"].setObjectName("bsSliderValue")
self.controls["bs_slider_value"].setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
self.controls["bs_slider_value"].setFixedWidth(40)
self.layouts["bs_slider_layout"].addWidget(self.controls["bs_slider_value"])
# 添加滑块
self.layouts["bs_slider_layout"].addWidget(self.controls["bs_slider"])
# 添加"All"勾选框和标签
self.controls["bs_slider_all_check"] = QtWidgets.QCheckBox("All")
self.controls["bs_slider_all_check"].setObjectName("bsSliderAllCheck")
self.layouts["bs_slider_layout"].addWidget(self.controls["bs_slider_all_check"])
# BlendShape操作按钮
self.buttons["reset_blendshape"] = QtWidgets.QPushButton(LANG.get("reset_blendshape", "重置混合形状"))
self.buttons["reset_blendshape"].setObjectName("resetBlendshapeButton")
self.buttons["flip_target"] = QtWidgets.QPushButton("Flip Target")
self.buttons["flip_target"].setObjectName("flipTargetButton")
self.buttons["flip_target"].setIcon(ui_utils.get_icon("mirrorL.png"))
self.buttons["flip_target"].setMinimumHeight(25) # 设置最小高度,确保按钮可见
self.buttons["mirror_blendshape"] = QtWidgets.QPushButton(LANG.get("mirror_blendshape", "镜像混合形状"))
self.buttons["mirror_blendshape"].setObjectName("mirrorBlendshapeButton")
self.buttons["mirror_target"] = QtWidgets.QPushButton("Mirror Target")
self.buttons["mirror_target"].setObjectName("mirrorTargetButton")
self.buttons["mirror_target"].setIcon(ui_utils.get_icon("mirror.png"))
self.buttons["mirror_target"].setMinimumHeight(25) # 设置最小高度,确保按钮可见
self.buttons["add_blendshape"] = QtWidgets.QPushButton(LANG.get("add_blendshape", "添加混合形状"))
self.buttons["find_flip_target"] = QtWidgets.QPushButton("Find Flip Target")
self.buttons["find_flip_target"].setObjectName("findFlipTargetButton")
self.buttons["find_flip_target"].setIcon(ui_utils.get_icon("mirrorR.png"))
self.buttons["find_flip_target"].setMinimumHeight(25) # 设置最小高度,确保按钮可见
self.buttons["add_blendshape"] = QtWidgets.QPushButton("Add BlendShape")
self.buttons["add_blendshape"].setObjectName("addBlendshapeButton")
self.buttons["add_blendshape"].setIcon(ui_utils.get_icon("blendShape.png"))
self.buttons["add_blendshape"].setMinimumHeight(25) # 设置最小高度,确保按钮可见
self.buttons["remove_blendshape"] = QtWidgets.QPushButton(LANG.get("remove_blendshape", "移除混合形状"))
self.buttons["remove_blendshape"].setObjectName("removeBlendshapeButton")
self.buttons["delete_blendshape"] = QtWidgets.QPushButton("Delete BlendShape")
self.buttons["delete_blendshape"].setObjectName("deleteBlendshapeButton")
self.buttons["delete_blendshape"].setIcon(ui_utils.get_icon("blendShape.png"))
self.buttons["delete_blendshape"].setMinimumHeight(25) # 设置最小高度,确保按钮可见
self.buttons["update_blendshape"] = QtWidgets.QPushButton(LANG.get("update_blendshape", "更新混合形状"))
self.buttons["update_blendshape"].setObjectName("updateBlendshapeButton")
self.buttons["batch_blendshape"] = QtWidgets.QPushButton("Batch BlendShape")
self.buttons["batch_blendshape"].setObjectName("batchBlendshapeButton")
self.buttons["batch_blendshape"].setIcon(ui_utils.get_icon("blendShape.png"))
self.buttons["batch_blendshape"].setMinimumHeight(25) # 设置最小高度,确保按钮可见
self.buttons["isolate_blendshape"] = QtWidgets.QPushButton(LANG.get("isolate_blendshape", "隔离混合形状"))
self.buttons["isolate_blendshape"].setObjectName("isolateBlendshapeButton")
self.buttons["rebuild_select"] = QtWidgets.QPushButton("Rebuild Select")
self.buttons["rebuild_select"].setObjectName("rebuildSelectButton")
self.buttons["rebuild_select"].setIcon(ui_utils.get_icon("loading.png"))
self.buttons["rebuild_select"].setMinimumHeight(25) # 设置最小高度,确保按钮可见
self.buttons["new_blendshape"] = QtWidgets.QPushButton(LANG.get("new_blendshape", "新建混合形状"))
self.buttons["new_blendshape"].setObjectName("newBlendshapeButton")
self.buttons["reposition_joints"] = QtWidgets.QPushButton("Reposition Joints")
self.buttons["reposition_joints"].setObjectName("repositionJointsButton")
self.buttons["reposition_joints"].setIcon(ui_utils.get_icon("loading.png"))
self.buttons["reposition_joints"].setMinimumHeight(25) # 设置最小高度,确保按钮可见
self.buttons["combine_blendshape"] = QtWidgets.QPushButton(LANG.get("combine_blendshape", "组合混合形状"))
self.buttons["combine_blendshape"].setObjectName("combineBlendshapeButton")
self.buttons["blend_select"] = QtWidgets.QPushButton("Blend Select")
self.buttons["blend_select"].setObjectName("blendSelectButton")
self.buttons["blend_select"].setIcon(ui_utils.get_icon("loading.png"))
self.buttons["blend_select"].setMinimumHeight(25) # 设置最小高度,确保按钮可见
# 右侧Range按钮
self.buttons["bs_range_plus"] = QtWidgets.QPushButton("Range +")
self.buttons["bs_range_plus"].setObjectName("bsRangePlusButton")
self.buttons["bs_range_plus"].setIcon(ui_utils.get_icon("behaviour.png"))
self.buttons["bs_range_minus"] = QtWidgets.QPushButton("Range -")
self.buttons["bs_range_minus"].setObjectName("bsRangeMinusButton")
self.buttons["bs_range_minus"].setIcon(ui_utils.get_icon("behaviour.png"))
# 底部标签页按钮
self.buttons["tab_bs"] = QtWidgets.QPushButton("BS")
self.buttons["tab_bs"].setObjectName("tabBsButton")
self.buttons["tab_bs"].setCheckable(True)
self.buttons["tab_bs"].setChecked(True)
self.buttons["tab_psd"] = QtWidgets.QPushButton("PSD")
self.buttons["tab_psd"].setIcon(ui_utils.get_icon("psd.png"))
self.buttons["tab_psd"].setObjectName("tabPsdButton")
self.buttons["tab_psd"].setCheckable(True)
self.buttons["tab_bse"] = QtWidgets.QPushButton("BSE")
self.buttons["tab_bse"].setIcon(ui_utils.get_icon("blendShape.png"))
self.buttons["tab_bse"].setObjectName("tabBseButton")
self.buttons["tab_bse"].setCheckable(True)
self.buttons["tab_key"] = QtWidgets.QPushButton("KEY")
self.buttons["tab_key"].setIcon(ui_utils.get_icon("setKeyOnAnim.png"))
self.buttons["tab_key"].setObjectName("tabKeyButton")
self.buttons["tab_key"].setCheckable(True)
self.buttons["tab_jnt"] = QtWidgets.QPushButton("JNT")
self.buttons["tab_jnt"].setObjectName("tabJntButton")
self.buttons["tab_jnt"].setCheckable(True)
self.buttons["tab_mir"] = QtWidgets.QPushButton("MIR")
self.buttons["tab_mir"].setIcon(ui_utils.get_icon("mirrorR.png"))
self.buttons["tab_mir"].setObjectName("tabMirButton")
self.buttons["tab_mir"].setCheckable(True)
self.buttons["tab_ark"] = QtWidgets.QPushButton("ARK")
self.buttons["tab_ark"].setIcon(ui_utils.get_icon("ARKit52.png"))
self.buttons["tab_ark"].setObjectName("tabArkButton")
self.buttons["tab_ark"].setCheckable(True)
self.buttons["tab_ctr"] = QtWidgets.QPushButton("CTR")
self.buttons["tab_ctr"].setIcon(ui_utils.get_icon("ctrl_hide.png"))
self.buttons["tab_ctr"].setObjectName("tabCtrButton")
self.buttons["tab_ctr"].setCheckable(True)
# 底部滑块
# 底部滑块
self.controls["bottom_main_slider"] = QtWidgets.QSlider(QtCore.Qt.Horizontal)
self.controls["bottom_main_slider"].setObjectName("bottomMainSlider")
self.controls["bottom_main_slider"].setMinimum(0)
self.controls["bottom_main_slider"].setMaximum(100)
self.controls["bottom_main_slider"].setValue(0)
self.controls["bottom_main_slider"].setFixedHeight(20)
# 底部按钮
self.buttons["exchange_from_expression"] = QtWidgets.QPushButton(LANG.get("exchange_from_expression", "交换从表情"))
self.buttons["exchange_from_expression"].setObjectName("exchangeFromExpressionButton")
# 底部主滑块布局包含数值显示和All勾选框
self.layouts["bottom_slider_layout"] = QtWidgets.QHBoxLayout()
self.layouts["bottom_slider_layout"].setContentsMargins(0, 0, 0, 0)
self.layouts["bottom_slider_layout"].setSpacing(2)
self.buttons["reset_selected_expression"] = QtWidgets.QPushButton(LANG.get("reset_selected_expression", "重置选定表情"))
self.buttons["reset_selected_expression"].setObjectName("resetSelectedExpressionButton")
# 添加数值显示标签
self.controls["bottom_slider_value"] = QtWidgets.QLabel("0.000")
self.controls["bottom_slider_value"].setObjectName("bottomSliderValue")
self.controls["bottom_slider_value"].setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
self.controls["bottom_slider_value"].setFixedWidth(40)
self.layouts["bottom_slider_layout"].addWidget(self.controls["bottom_slider_value"])
self.buttons["import_expression"] = QtWidgets.QPushButton(LANG.get("import_expression", "导入表情"))
self.buttons["import_expression"].setObjectName("importExpressionButton")
# 添加滑块
self.layouts["bottom_slider_layout"].addWidget(self.controls["bottom_main_slider"])
self.buttons["control_panel_search"] = QtWidgets.QPushButton(LANG.get("control_panel_search", "控制面板搜索"))
self.buttons["control_panel_search"].setObjectName("controlPanelSearchButton")
# 添加"All"勾选框
self.controls["bottom_slider_all_check"] = QtWidgets.QCheckBox("All")
self.controls["bottom_slider_all_check"].setObjectName("bottomSliderAllCheck")
self.layouts["bottom_slider_layout"].addWidget(self.controls["bottom_slider_all_check"])
self.buttons["select_related_keys"] = QtWidgets.QPushButton(LANG.get("select_related_keys", "选择相关键值"))
self.buttons["select_related_keys"].setObjectName("selectRelatedKeysButton")
# 底部功能按钮
self.buttons["reset_default_expression"] = QtWidgets.QPushButton("Reset Default Expression")
self.buttons["reset_default_expression"].setIcon(ui_utils.get_icon("reset.png"))
self.buttons["reset_default_expression"].setObjectName("resetDefaultExpressionButton")
self.buttons["import_map_expression"] = QtWidgets.QPushButton(LANG.get("import_map_expression", "导入表情映射"))
self.buttons["import_map_expression"].setObjectName("importMapExpressionButton")
# 表情控制按钮
self.buttons["reset_expression"] = QtWidgets.QPushButton(LANG.get("reset_expression", "还原默认表情"))
self.buttons["find_expression"] = QtWidgets.QPushButton(LANG.get("find_expression", "查找选择表情"))
self.buttons["find_control_panel"] = QtWidgets.QPushButton(LANG.get("find_control_panel", "控制面板查找"))
self.buttons["find_select_expression"] = QtWidgets.QPushButton("Find Select Expression")
self.buttons["find_select_expression"].setIcon(ui_utils.get_icon("expressions_current.png"))
self.buttons["find_select_expression"].setObjectName("findSelectExpressionButton")
self.buttons["write_current_expressions"] = QtWidgets.QPushButton("Write Current Expressions")
self.buttons["write_current_expressions"].setIcon(ui_utils.get_icon("expression.png"))
self.buttons["write_current_expressions"].setObjectName("writeCurrentExpressionsButton")
self.buttons["controller_find"] = QtWidgets.QPushButton("Controller Find")
self.buttons["controller_find"].setIcon(ui_utils.get_icon("controller.png"))
self.buttons["controller_find"].setObjectName("controllerFindButton")
self.buttons["select_associated_joint"] = QtWidgets.QPushButton("Select Associated Joint")
self.buttons["select_associated_joint"].setIcon(ui_utils.get_icon("out_joint.png"))
self.buttons["select_associated_joint"].setObjectName("selectAssociatedJointButton")
self.buttons["write_find_mirror"] = QtWidgets.QPushButton("Write Find Mirror")
self.buttons["write_find_mirror"].setIcon(ui_utils.get_icon("mirror.png"))
self.buttons["write_find_mirror"].setObjectName("writeFindMirrorButton")
#========================================= LAYOUT =======================================
def create_layouts(self):
"""
创建行为系统UI布局
安排控件的位置和尺寸
包括主布局、左右面板布局等
"""
# 主布局
self.layouts["main_layout"] = QtWidgets.QVBoxLayout(self.main_widget)
self.layouts["main_layout"].setContentsMargins(2, 2, 2, 2)
self.layouts["main_layout"].setSpacing(2)
self.layouts["main_layout"].setContentsMargins(0, 0, 0, 0)
self.layouts["main_layout"].setSpacing(0)
# 添加标题标签
self.layouts["main_layout"].addWidget(self.controls["title_label"])
@@ -266,70 +419,136 @@ class BehaviourUI(ui_utils.BaseUI):
# 创建主分割器
self.splitters["main_splitter"] = QtWidgets.QSplitter(QtCore.Qt.Horizontal)
self.splitters["main_splitter"].setObjectName("behaviourMainSplitter")
self.layouts["main_layout"].addWidget(self.splitters["main_splitter"])
self.splitters["main_splitter"].setHandleWidth(6) # 设置分割器手柄宽度
self.splitters["main_splitter"].setChildrenCollapsible(False) # 禁止子部件折叠
self.splitters["main_splitter"].setOpaqueResize(True) # 实时显示调整效果,更丝滑
# 添加主分割器
self.layouts["main_layout"].addWidget(self.splitters["main_splitter"], 1) # 设置伸缩因子为1使其占据剩余空间
# 左侧面板
self.controls["left_panel"] = QtWidgets.QWidget()
self.controls["left_panel"].setObjectName("behaviourLeftPanel")
self.controls["left_panel"].setMinimumWidth(0)
self.controls["left_panel"].setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
# 右侧面板
self.controls["right_panel"] = QtWidgets.QWidget()
self.controls["right_panel"].setObjectName("behaviourRightPanel")
self.controls["right_panel"].setMinimumWidth(0)
self.controls["right_panel"].setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
# 将左右面板添加到分割器
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)
# Raw Control组布局
self.layouts["raw_control_layout"] = QtWidgets.QVBoxLayout(self.controls["raw_control_group"])
self.layouts["raw_control_layout"].setContentsMargins(5, 10, 5, 5)
self.layouts["raw_control_layout"].setSpacing(5)
# 搜索框
self.layouts["raw_control_layout"].addWidget(self.controls["search_input"])
# 控制列表
self.layouts["raw_control_layout"].addWidget(self.controls["control_list"])
# 底部滑块
self.layouts["raw_control_layout"].addWidget(self.controls["bottom_slider"])
# 页码按钮行
self.layouts["page_buttons_layout"] = QtWidgets.QHBoxLayout()
self.layouts["page_buttons_layout"].setContentsMargins(0, 0, 0, 0)
self.layouts["page_buttons_layout"].setSpacing(2)
self.layouts["page_buttons_layout"].addWidget(self.buttons["page_all"])
self.layouts["page_buttons_layout"].addWidget(self.buttons["page_2"])
self.layouts["page_buttons_layout"].addWidget(self.buttons["page_3"])
self.layouts["page_buttons_layout"].addWidget(self.buttons["page_4"])
self.layouts["page_buttons_layout"].addWidget(self.buttons["page_5"])
self.layouts["page_buttons_layout"].addWidget(self.buttons["page_6"])
self.layouts["raw_control_layout"].addLayout(self.layouts["page_buttons_layout"])
# 左下角按钮行
self.layouts["range_buttons_layout"] = QtWidgets.QHBoxLayout()
self.layouts["range_buttons_layout"].setContentsMargins(0, 0, 0, 0)
self.layouts["range_buttons_layout"].setSpacing(2)
self.layouts["range_buttons_layout"].addWidget(self.buttons["range_minus"])
self.layouts["range_buttons_layout"].addWidget(self.buttons["range_plus"])
self.layouts["range_buttons_layout"].addStretch()
self.layouts["raw_control_layout"].addLayout(self.layouts["range_buttons_layout"])
# 添加Raw Control组到左侧面板
self.layouts["left_layout"].addWidget(self.controls["raw_control_group"])
# 右侧面板布局
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)
# BlendShapes组布局
self.layouts["blendshapes_layout"] = QtWidgets.QVBoxLayout(self.controls["blendshapes_group"])
self.layouts["blendshapes_layout"].setContentsMargins(5, 10, 5, 5)
self.layouts["blendshapes_layout"].setSpacing(5)
# 左侧面板控件 - Raw Control
self.controls["raw_control_group"] = QtWidgets.QGroupBox("Raw Control")
self.controls["raw_control_group"].setObjectName("rawControlGroup")
self.controls["raw_control_group"].setMinimumWidth(0) # 设置最小宽度为零
self.controls["raw_control_group"].setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
# BlendShapes列表
self.layouts["blendshapes_layout"].addWidget(self.controls["blendshapes_list"])
# 左侧面板控件布局
self.layouts["raw_control_layout"] = QtWidgets.QVBoxLayout()
self.layouts["raw_control_layout"].setContentsMargins(2, 2, 2, 2)
self.layouts["raw_control_layout"].setSpacing(2)
self.controls["raw_control_group"].setLayout(self.layouts["raw_control_layout"])
# 滑块
self.layouts["blendshapes_layout"].addWidget(self.controls["bs_slider"])
# 添加控制列表到Raw Control布局
self.layouts["raw_control_layout"].addWidget(self.controls["control_list"])
# 左侧滑块布局
self.layouts["raw_control_layout"].addLayout(self.layouts["raw_slider_layout"])
# 范围调整按钮布局
self.layouts["range_buttons_layout"] = QtWidgets.QHBoxLayout()
self.layouts["range_buttons_layout"].setContentsMargins(0, 0, 0, 0)
self.layouts["range_buttons_layout"].setSpacing(2)
# 设置Range按钮的策略使其均等撑满一行
size_policy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
self.buttons["range_plus"].setSizePolicy(size_policy)
self.buttons["range_minus"].setSizePolicy(size_policy)
self.layouts["range_buttons_layout"].addWidget(self.buttons["range_plus"])
self.layouts["range_buttons_layout"].addWidget(self.buttons["range_minus"])
# 添加范围按钮布局到Raw Control布局
self.layouts["raw_control_layout"].addLayout(self.layouts["range_buttons_layout"])
# 页码按钮布局
self.layouts["page_buttons_layout"] = QtWidgets.QHBoxLayout()
self.layouts["page_buttons_layout"].setContentsMargins(0, 0, 0, 0)
self.layouts["page_buttons_layout"].setSpacing(2)
# 设置页码按钮的策略,使其均等撑满一行
for button_name in ["prev_page", "next_page", "page_all", "page_2", "page_3", "page_4", "page_5", "page_6"]:
if button_name in self.buttons:
self.buttons[button_name].setSizePolicy(size_policy)
# 添加页码按钮到布局
for button_name in ["prev_page", "next_page", "page_all", "page_2", "page_3", "page_4", "page_5", "page_6"]:
if button_name in self.buttons:
self.layouts["page_buttons_layout"].addWidget(self.buttons[button_name])
# 添加页码按钮布局到Raw Control布局
self.layouts["raw_control_layout"].addLayout(self.layouts["page_buttons_layout"])
# 添加Raw Control组到左侧面板
self.layouts["left_layout"].addWidget(self.controls["raw_control_group"])
# 右侧面板控件 - Related BlendShapes
self.controls["blendshapes_group"] = QtWidgets.QGroupBox("Related BlendShapes")
self.controls["blendshapes_group"].setObjectName("blendshapesGroup")
self.controls["blendshapes_group"].setMinimumWidth(0) # 设置最小宽度为零
self.controls["blendshapes_group"].setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
# 右侧面板控件布局
self.layouts["blendshapes_layout"] = QtWidgets.QVBoxLayout()
self.layouts["blendshapes_layout"].setContentsMargins(2, 2, 2, 2)
self.layouts["blendshapes_layout"].setSpacing(2)
self.controls["blendshapes_group"].setLayout(self.layouts["blendshapes_layout"])
# 添加BlendShapes列表到BlendShapes布局
self.layouts["blendshapes_layout"].addWidget(self.controls["blendshapes_list"], 1) # 设置伸缩因子为1使其占据更多空间
# 右侧滑块布局
self.layouts["blendshapes_layout"].addLayout(self.layouts["bs_slider_layout"])
# BS范围调整按钮布局
self.layouts["bs_range_buttons_layout"] = QtWidgets.QHBoxLayout()
self.layouts["bs_range_buttons_layout"].setContentsMargins(0, 0, 0, 0)
self.layouts["bs_range_buttons_layout"].setSpacing(2)
# 设置BS Range按钮的策略使其均等撑满一行
size_policy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
self.buttons["bs_range_plus"].setSizePolicy(size_policy)
self.buttons["bs_range_minus"].setSizePolicy(size_policy)
self.layouts["bs_range_buttons_layout"].addWidget(self.buttons["bs_range_plus"])
self.layouts["bs_range_buttons_layout"].addWidget(self.buttons["bs_range_minus"])
# 添加BS范围按钮布局到BlendShapes布局
self.layouts["blendshapes_layout"].addLayout(self.layouts["bs_range_buttons_layout"])
# 为所有按钮设置统一的大小策略
for button_name in ["flip_target", "mirror_target", "find_flip_target",
"add_blendshape", "delete_blendshape", "batch_blendshape",
"rebuild_select", "reposition_joints", "blend_select"]:
if button_name in self.buttons:
self.buttons[button_name].setMinimumWidth(0)
self.buttons[button_name].setMinimumHeight(25) # 设置最小高度,确保按钮可见
self.buttons[button_name].setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
# BlendShape操作按钮网格
self.layouts["bs_buttons_grid"] = QtWidgets.QGridLayout()
@@ -337,136 +556,123 @@ class BehaviourUI(ui_utils.BaseUI):
self.layouts["bs_buttons_grid"].setSpacing(2)
# 添加按钮到网格
self.layouts["bs_buttons_grid"].addWidget(self.buttons["reset_blendshape"], 0, 0)
self.layouts["bs_buttons_grid"].addWidget(self.buttons["mirror_blendshape"], 0, 1)
self.layouts["bs_buttons_grid"].addWidget(self.buttons["flip_target"], 0, 0)
self.layouts["bs_buttons_grid"].addWidget(self.buttons["mirror_target"], 0, 1)
self.layouts["bs_buttons_grid"].addWidget(self.buttons["find_flip_target"], 0, 2)
self.layouts["bs_buttons_grid"].addWidget(self.buttons["add_blendshape"], 1, 0)
self.layouts["bs_buttons_grid"].addWidget(self.buttons["remove_blendshape"], 1, 1)
self.layouts["bs_buttons_grid"].addWidget(self.buttons["update_blendshape"], 2, 0)
self.layouts["bs_buttons_grid"].addWidget(self.buttons["isolate_blendshape"], 2, 1)
self.layouts["bs_buttons_grid"].addWidget(self.buttons["new_blendshape"], 3, 0)
self.layouts["bs_buttons_grid"].addWidget(self.buttons["combine_blendshape"], 3, 1)
self.layouts["bs_buttons_grid"].addWidget(self.buttons["delete_blendshape"], 1, 1)
self.layouts["bs_buttons_grid"].addWidget(self.buttons["batch_blendshape"], 1, 2)
self.layouts["bs_buttons_grid"].addWidget(self.buttons["rebuild_select"], 2, 0)
self.layouts["bs_buttons_grid"].addWidget(self.buttons["reposition_joints"], 2, 1)
self.layouts["bs_buttons_grid"].addWidget(self.buttons["blend_select"], 2, 2)
# 添加按钮网格到BlendShapes布局
self.layouts["blendshapes_layout"].addLayout(self.layouts["bs_buttons_grid"])
# 标签页按钮行
# 添加BlendShapes组到右侧面板
self.layouts["right_layout"].addWidget(self.controls["blendshapes_group"], 1) # 设置伸缩因子为1使其占据更多空间
# 底部标签页按钮行
self.layouts["tab_buttons_layout"] = QtWidgets.QHBoxLayout()
self.layouts["tab_buttons_layout"].setContentsMargins(0, 0, 0, 0)
self.layouts["tab_buttons_layout"].setSpacing(2)
self.layouts["tab_buttons_layout"].setSpacing(0)
self.layouts["tab_buttons_layout"].addWidget(self.buttons["tab_bs"])
self.layouts["tab_buttons_layout"].addWidget(self.buttons["tab_psd"])
self.layouts["tab_buttons_layout"].addWidget(self.buttons["tab_key"])
self.layouts["tab_buttons_layout"].addWidget(self.buttons["tab_jnt"])
self.layouts["tab_buttons_layout"].addWidget(self.buttons["tab_ark"])
self.layouts["tab_buttons_layout"].addWidget(self.buttons["tab_ctr"])
# 设置标签页按钮的策略,使其均等撑满一行
for button_name in ["tab_psd", "tab_bse", "tab_key", "tab_mir", "tab_ark", "tab_ctr"]:
if button_name in self.buttons:
self.buttons[button_name].setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
self.layouts["tab_buttons_layout"].addWidget(self.buttons[button_name])
self.layouts["blendshapes_layout"].addLayout(self.layouts["tab_buttons_layout"])
# 添加标签页按钮行到主布局
self.layouts["main_layout"].addLayout(self.layouts["tab_buttons_layout"])
# 添加BlendShapes组到右侧面板
self.layouts["right_layout"].addWidget(self.controls["blendshapes_group"])
# 底部按钮布局
self.layouts["bottom_buttons_layout"] = QtWidgets.QVBoxLayout()
self.layouts["bottom_buttons_layout"].setContentsMargins(0, 0, 0, 0)
self.layouts["bottom_buttons_layout"].setSpacing(5)
# 底部工具面板
self.layouts["bottom_panel"] = QtWidgets.QVBoxLayout()
self.layouts["bottom_panel"].setContentsMargins(2, 2, 2, 2)
self.layouts["bottom_panel"].setSpacing(2)
# 第一行按钮
self.layouts["bottom_buttons_row1"] = QtWidgets.QHBoxLayout()
self.layouts["bottom_buttons_row1"].setContentsMargins(0, 0, 0, 0)
self.layouts["bottom_buttons_row1"].setSpacing(5)
# 底部滑块
self.layouts["bottom_panel"].addWidget(self.controls["bottom_main_slider"])
self.layouts["bottom_buttons_row1"].addWidget(self.buttons["reset_default_expression"])
self.layouts["bottom_buttons_row1"].addWidget(self.buttons["find_select_expression"])
self.layouts["bottom_buttons_row1"].addWidget(self.buttons["write_current_expressions"])
# 底部按钮网格
self.layouts["bottom_buttons_grid"] = QtWidgets.QGridLayout()
self.layouts["bottom_buttons_grid"].setContentsMargins(0, 0, 0, 0)
self.layouts["bottom_buttons_grid"].setSpacing(2)
# 第二行按钮
self.layouts["bottom_buttons_row2"] = QtWidgets.QHBoxLayout()
self.layouts["bottom_buttons_row2"].setContentsMargins(0, 0, 0, 0)
self.layouts["bottom_buttons_row2"].setSpacing(5)
# 添加底部按钮
self.layouts["bottom_buttons_grid"].addWidget(self.buttons["exchange_from_expression"], 0, 0)
self.layouts["bottom_buttons_grid"].addWidget(self.buttons["reset_selected_expression"], 0, 1)
self.layouts["bottom_buttons_grid"].addWidget(self.buttons["import_expression"], 0, 2)
self.layouts["bottom_buttons_grid"].addWidget(self.buttons["control_panel_search"], 1, 0)
self.layouts["bottom_buttons_grid"].addWidget(self.buttons["select_related_keys"], 1, 1)
self.layouts["bottom_buttons_grid"].addWidget(self.buttons["import_map_expression"], 1, 2)
self.layouts["bottom_buttons_row2"].addWidget(self.buttons["controller_find"])
self.layouts["bottom_buttons_row2"].addWidget(self.buttons["select_associated_joint"])
self.layouts["bottom_buttons_row2"].addWidget(self.buttons["write_find_mirror"])
self.layouts["bottom_panel"].addLayout(self.layouts["bottom_buttons_grid"])
# 将两行按钮添加到底部按钮布局
self.layouts["bottom_buttons_layout"].addLayout(self.layouts["bottom_buttons_row1"])
self.layouts["bottom_buttons_layout"].addLayout(self.layouts["bottom_buttons_row2"])
# 添加底部面板到主布局
self.layouts["main_layout"].addLayout(self.layouts["bottom_panel"])
# 添加底部按钮布局到主布局
self.layouts["main_layout"].addLayout(self.layouts["bottom_buttons_layout"])
# 将左右面板添加到主分割器
self.splitters["main_splitter"].addWidget(self.controls["left_panel"])
self.splitters["main_splitter"].addWidget(self.controls["right_panel"])
# 底部主滑块布局
self.layouts["main_layout"].addLayout(self.layouts["bottom_slider_layout"])
# 设置分割器初始大小和伸缩因子
self.splitters["main_splitter"].setSizes([500, 500])
# 设置分割器的伸缩因子,确保左右栏能够自动调整宽度
for i in range(self.splitters["main_splitter"].count()):
self.splitters["main_splitter"].setStretchFactor(i, 1)
#======================================= CONNECTION =====================================
def create_connections(self):
"""
连接信号和槽
设置UI控件的交互行为
创建信号连接
连接按钮点击事件和其他UI事件
"""
# 导入行为工具函数
from scripts.utils import utils_behaviour
# 创建信号映射字典
signal_mapping = {
'buttons': {
# 底部标签页按钮
'tab_psd': {'signal': 'clicked', 'handler': lambda: utils_behaviour.switch_tab(0)},
'tab_bse': {'signal': 'clicked', 'handler': lambda: utils_behaviour.switch_tab(1)},
'tab_key': {'signal': 'clicked', 'handler': lambda: utils_behaviour.switch_tab(2)},
'tab_mir': {'signal': 'clicked', 'handler': lambda: utils_behaviour.switch_tab(3)},
'tab_ark': {'signal': 'clicked', 'handler': lambda: utils_behaviour.switch_tab(4)},
'tab_ctr': {'signal': 'clicked', 'handler': lambda: utils_behaviour.switch_tab(5)},
# 功能按钮
'flip_target': {'signal': 'clicked', 'handler': utils_behaviour.flip_target},
'mirror_target': {'signal': 'clicked', 'handler': utils_behaviour.mirror_target},
'find_flip_target': {'signal': 'clicked', 'handler': utils_behaviour.find_flip_target},
'add_blendshape': {'signal': 'clicked', 'handler': utils_behaviour.add_blendshape},
'delete_blendshape': {'signal': 'clicked', 'handler': utils_behaviour.delete_blendshape},
'batch_blendshape': {'signal': 'clicked', 'handler': utils_behaviour.batch_blendshape},
'rebuild_select': {'signal': 'clicked', 'handler': utils_behaviour.rebuild_select},
'reposition_joints': {'signal': 'clicked', 'handler': utils_behaviour.reposition_joints},
'blend_select': {'signal': 'clicked', 'handler': utils_behaviour.blend_select},
'reset_default_expression': {'signal': 'clicked', 'handler': utils_behaviour.reset_default_expression},
'find_select_expression': {'signal': 'clicked', 'handler': utils_behaviour.find_select_expression},
'write_current_expressions': {'signal': 'clicked', 'handler': utils_behaviour.write_current_expressions},
'controller_find': {'signal': 'clicked', 'handler': utils_behaviour.controller_find},
'select_associated_joint': {'signal': 'clicked', 'handler': utils_behaviour.select_associated_joint},
'write_find_mirror': {'signal': 'clicked', 'handler': utils_behaviour.write_find_mirror},
# 范围按钮
'range_plus': {'signal': 'clicked', 'handler': lambda: utils_behaviour.adjust_range(0.1)},
'range_minus': {'signal': 'clicked', 'handler': lambda: utils_behaviour.adjust_range(-0.1)},
'bs_range_plus': {'signal': 'clicked', 'handler': lambda: utils_behaviour.adjust_bs_range(0.1)},
'bs_range_minus': {'signal': 'clicked', 'handler': lambda: utils_behaviour.adjust_bs_range(-0.1)},
},
'controls': {
# 滑块控件
'raw_slider': {'signal': 'valueChanged', 'handler': utils_behaviour.on_raw_slider_changed},
'bs_slider': {'signal': 'valueChanged', 'handler': utils_behaviour.on_bs_slider_changed},
'bottom_main_slider': {'signal': 'valueChanged', 'handler': utils_behaviour.on_bottom_slider_changed},
# 列表控件
'control_list': {'signal': 'itemSelectionChanged', 'handler': utils_behaviour.on_control_selection_changed},
'blendshapes_list': {'signal': 'itemSelectionChanged', 'handler': utils_behaviour.on_blendshape_selection_changed},
}
}
# 左侧面板连接
# 搜索框连接
self.controls["search_input"].textChanged.connect(utils_behaviour.filter_controls)
# 使用ui_utils中的函数连接信号
ui_utils.connect_ui_signals(self, signal_mapping)
# 控制列表连接
self.controls["control_list"].itemClicked.connect(utils_behaviour.control_selected)
self.controls["control_list"].itemSelectionChanged.connect(utils_behaviour.update_control_selection)
# 底部滑块连接
self.controls["bottom_slider"].valueChanged.connect(utils_behaviour.update_control_value)
# 页码按钮连接
self.buttons["page_all"].clicked.connect(lambda: utils_behaviour.switch_page("all"))
self.buttons["page_2"].clicked.connect(lambda: utils_behaviour.switch_page("2"))
self.buttons["page_3"].clicked.connect(lambda: utils_behaviour.switch_page("3"))
self.buttons["page_4"].clicked.connect(lambda: utils_behaviour.switch_page("4"))
self.buttons["page_5"].clicked.connect(lambda: utils_behaviour.switch_page("5"))
self.buttons["page_6"].clicked.connect(lambda: utils_behaviour.switch_page("6"))
# 左下角按钮连接
self.buttons["range_minus"].clicked.connect(utils_behaviour.decrease_range)
self.buttons["range_plus"].clicked.connect(utils_behaviour.increase_range)
# 右侧面板连接
# BlendShapes列表连接
self.controls["blendshapes_list"].itemClicked.connect(utils_behaviour.blendshape_selected)
self.controls["blendshapes_list"].itemSelectionChanged.connect(utils_behaviour.update_blendshape_selection)
# 滑块连接
self.controls["bs_slider"].valueChanged.connect(utils_behaviour.update_blendshape_value)
# BlendShape操作按钮连接
self.buttons["reset_blendshape"].clicked.connect(utils_behaviour.reset_blendshape)
self.buttons["mirror_blendshape"].clicked.connect(utils_behaviour.mirror_blendshape)
self.buttons["add_blendshape"].clicked.connect(utils_behaviour.add_blendshape)
self.buttons["remove_blendshape"].clicked.connect(utils_behaviour.remove_blendshape)
self.buttons["update_blendshape"].clicked.connect(utils_behaviour.update_blendshape)
self.buttons["isolate_blendshape"].clicked.connect(utils_behaviour.isolate_blendshape)
self.buttons["new_blendshape"].clicked.connect(utils_behaviour.new_blendshape)
self.buttons["combine_blendshape"].clicked.connect(utils_behaviour.combine_blendshape)
# 标签页按钮连接
self.buttons["tab_bs"].clicked.connect(lambda: utils_behaviour.switch_tab("bs"))
self.buttons["tab_psd"].clicked.connect(lambda: utils_behaviour.switch_tab("psd"))
self.buttons["tab_key"].clicked.connect(lambda: utils_behaviour.switch_tab("key"))
self.buttons["tab_jnt"].clicked.connect(lambda: utils_behaviour.switch_tab("jnt"))
self.buttons["tab_ark"].clicked.connect(lambda: utils_behaviour.switch_tab("ark"))
self.buttons["tab_ctr"].clicked.connect(lambda: utils_behaviour.switch_tab("ctr"))
# 底部滑块连接
self.controls["bottom_main_slider"].valueChanged.connect(utils_behaviour.update_main_value)
# 底部按钮连接
self.buttons["exchange_from_expression"].clicked.connect(utils_behaviour.exchange_from_expression)
self.buttons["reset_selected_expression"].clicked.connect(utils_behaviour.reset_selected_expression)
self.buttons["import_expression"].clicked.connect(utils_behaviour.import_expression)
self.buttons["control_panel_search"].clicked.connect(utils_behaviour.control_panel_search)
self.buttons["select_related_keys"].clicked.connect(utils_behaviour.select_related_keys)
self.buttons["import_map_expression"].clicked.connect(utils_behaviour.import_map_expression)
# 连接Maya选择变化事件
ui_utils.connect_maya_selection_changed(self, lambda: utils_behaviour.on_selection_changed(self), self.main_widget)