This commit is contained in:
Jeffreytsai1004 2025-02-10 03:19:08 +08:00
parent 45ea47e336
commit 9a9d6fbe10
2 changed files with 320 additions and 216 deletions

View File

@ -295,28 +295,27 @@ Reference\UI\17_Definitions.jpg
第四行修复接缝icons\fix_seam.png
####### DNA预设浏览器
###### 2. 绑定视图 (Rigging)
- 预设角色图标矩阵 (6x6网格)
- 缩放控制滑块 (默认90)
- 导入/导出设置按钮
####### 预设
####### 资产设置
- DNA浏览器
- 图标缩放滑条; - 导入/导出设置按钮
- 项目路径设置
- 预设文件选择
- 数据分层选项
- 行为(包括描述和定义)
- 覆盖表情选项
- 描述设置:
- 名称Archetype
- 原型:其他
- 性别:女性
- 年龄24
- 变换单位:厘米
- 旋转单位:角度
- 向上轴标Z轴向上
- LOD计数8
####### 资产
- 项目路径: 输入框; 加载按钮
- 预设文件: 输入框; 加载按钮
- 数据分层: 下拉框(默认:行为(包括基础定义)); - 勾选框(勾选):覆盖表情
####### 描述
- 名称:输入框(默认:Archetype; - 变换单位:下拉框(默认:厘米)
- 原型:下拉框(默认:亚洲人); - 旋转单位:下拉框(默认:角度)
- 性别:下拉框(默认:女性 - 向上轴标下拉框默认Z轴向上
- 年龄:数值调节(默认:24 - LOD计数数值调节默认8
####### 功能按钮
- 清空选项icons\delete.png - 导入骨架icons\HIKCharacterToolSkeleton.png - 创建骨架icons\HIKcreateControlRig.png
###### 3. 行为视图 (Behaviour)

View File

@ -40,226 +40,331 @@ class RiggingTab(QtWidgets.QWidget):
def _setup_ui(self):
"""设置UI布局"""
# === Main Layout ===
self.main_layout = QtWidgets.QHBoxLayout(self)
self.main_layout.setContentsMargins(2, 2, 2, 2)
self.main_layout.setSpacing(2)
self.main_layout = QtWidgets.QVBoxLayout(self)
self.main_layout.setContentsMargins(0, 0, 0, 0)
self.main_layout.setSpacing(0)
# 创建左右两个主面板
self.dna_browser_widget = self._create_dna_browser()
self.asset_settings_widget = self._create_asset_settings()
# === DNA预览区域 ===
self.preview_area = self._create_preview_area()
# 设置左右比例为1:1
self.main_layout.addWidget(self.dna_browser_widget, 1)
self.main_layout.addWidget(self.asset_settings_widget, 1)
# === 设置区域 ===
self.settings_area = QtWidgets.QWidget()
settings_layout = QtWidgets.QVBoxLayout(self.settings_area)
settings_layout.setContentsMargins(8, 8, 8, 8)
settings_layout.setSpacing(4)
def _create_dna_browser(self):
"""创建DNA预设浏览器"""
# === Widget ===
widget = QtWidgets.QWidget()
# === Layout ===
layout = QtWidgets.QVBoxLayout(widget)
layout.setContentsMargins(5, 5, 5, 5)
layout.setSpacing(5)
# 预设网格视图
self.preset_view = QtWidgets.QListWidget()
self.preset_view.setViewMode(QtWidgets.QListView.IconMode)
self.preset_view.setIconSize(QtCore.QSize(90, 90))
self.preset_view.setSpacing(10)
self.preset_view.setResizeMode(QtWidgets.QListView.Adjust)
self.preset_view.setMovement(QtWidgets.QListView.Static)
self.preset_view.setWrapping(True)
layout.addWidget(self.preset_view)
# 缩放控制
zoom_widget = QtWidgets.QWidget()
zoom_layout = QtWidgets.QHBoxLayout(zoom_widget)
zoom_layout.setContentsMargins(0, 0, 0, 0)
zoom_label = QtWidgets.QLabel("缩放:")
self.zoom_slider = QtWidgets.QSlider(QtCore.Qt.Horizontal)
self.zoom_slider.setMinimum(60)
self.zoom_slider.setMaximum(200)
self.zoom_slider.setValue(90)
self.zoom_value_label = QtWidgets.QLabel("90")
zoom_layout.addWidget(zoom_label)
zoom_layout.addWidget(self.zoom_slider)
zoom_layout.addWidget(self.zoom_value_label)
layout.addWidget(zoom_widget)
# 导入/导出按钮
button_widget = QtWidgets.QWidget()
button_layout = QtWidgets.QHBoxLayout(button_widget)
button_layout.setContentsMargins(0, 0, 0, 0)
self.import_btn = QtWidgets.QPushButton("导入设置")
self.export_btn = QtWidgets.QPushButton("导出设置")
button_layout.addWidget(self.import_btn)
button_layout.addWidget(self.export_btn)
layout.addWidget(button_widget)
return widget
def _create_asset_settings(self):
"""创建资产设置面板"""
# === Widget ===
widget = QtWidgets.QWidget()
# === Layout ===
layout = QtWidgets.QVBoxLayout(widget)
layout.setContentsMargins(5, 5, 5, 5)
layout.setSpacing(5)
# 项目路径设置
self.project_group = self._create_project_settings()
layout.addWidget(self.project_group)
# 数据分层选项
self.layer_group = self._create_layer_settings()
layout.addWidget(self.layer_group)
# 描述设置
self.desc_group = self._create_description_settings()
layout.addWidget(self.desc_group)
layout.addStretch()
return widget
def _create_project_settings(self):
"""创建项目设置组"""
# === Widget ===
group = QtWidgets.QGroupBox("项目设置")
# === Layout ===
layout = QtWidgets.QFormLayout(group)
layout.setContentsMargins(5, 5, 5, 5)
layout.setSpacing(5)
# === 资产设置 ===
asset_group = QtWidgets.QWidget()
asset_layout = QtWidgets.QGridLayout(asset_group)
asset_layout.setContentsMargins(0, 0, 0, 0)
asset_layout.setSpacing(4)
# 项目路径
path_widget = QtWidgets.QWidget()
path_layout = QtWidgets.QHBoxLayout(path_widget)
path_layout.setContentsMargins(0, 0, 0, 0)
self.project_path = QtWidgets.QLineEdit()
self.browse_project_btn = QtWidgets.QPushButton("浏览...")
self.browse_project_btn.setFixedWidth(60)
path_layout.addWidget(self.project_path)
path_layout.addWidget(self.browse_project_btn)
layout.addRow("项目路径:", path_widget)
path_label = QtWidgets.QLabel("项目路径:")
self.path_edit = QtWidgets.QLineEdit()
self.path_edit.setText("D:/Personal/Document/maya/SuperRiggingEditor/files/data/MetaHuman")
self.path_btn = QtWidgets.QPushButton("加载...")
self.path_btn.setIcon(QtGui.QIcon(":fileOpen.png")) # 使用Maya内置图标
self.path_btn.setFixedWidth(60) # 调整按钮宽度
self.path_btn.setFixedHeight(24)
# 预设文件
preset_widget = QtWidgets.QWidget()
preset_layout = QtWidgets.QHBoxLayout(preset_widget)
preset_layout.setContentsMargins(0, 0, 0, 0)
preset_label = QtWidgets.QLabel("预设文件:")
self.preset_edit = QtWidgets.QLineEdit()
self.preset_edit.setText("nal/Document/maya/SuperRiggingEditor/files/presets/metahuman/MH_Ada.dna")
self.preset_btn = QtWidgets.QPushButton("加载...")
self.preset_btn.setIcon(QtGui.QIcon(":fileOpen.png")) # 使用Maya内置图标
self.preset_btn.setFixedWidth(60) # 调整按钮宽度
self.preset_btn.setFixedHeight(24)
self.preset_path = QtWidgets.QLineEdit()
self.browse_preset_btn = QtWidgets.QPushButton("浏览...")
self.browse_preset_btn.setFixedWidth(60)
# 数据分层
layer_label = QtWidgets.QLabel("数据分层:")
self.layer_combo = QtWidgets.QComboBox()
self.layer_combo.addItem("行为(包括基础定义)")
self.override_check = QtWidgets.QCheckBox("覆盖表情")
self.override_check.setChecked(True)
self.override_check.setStyleSheet("""
QCheckBox {
background: transparent;
}
QCheckBox::indicator {
width: 16px;
height: 16px;
background: #3D3D3D;
border: 1px solid #555555;
border-radius: 2px;
}
QCheckBox::indicator:checked {
background: #3D3D3D;
image: url(:checkboxChecked.png);
}
QCheckBox::indicator:unchecked {
background: #3D3D3D;
image: url(:checkboxUnchecked.png);
}
QCheckBox::indicator:hover {
border: 1px solid #666666;
}
""")
preset_layout.addWidget(self.preset_path)
preset_layout.addWidget(self.browse_preset_btn)
layout.addRow("预设文件:", preset_widget)
# 添加到资产布局
asset_layout.addWidget(path_label, 0, 0)
asset_layout.addWidget(self.path_edit, 0, 1)
asset_layout.addWidget(self.path_btn, 0, 2)
asset_layout.addWidget(preset_label, 1, 0)
asset_layout.addWidget(self.preset_edit, 1, 1)
asset_layout.addWidget(self.preset_btn, 1, 2)
asset_layout.addWidget(layer_label, 2, 0)
asset_layout.addWidget(self.layer_combo, 2, 1)
asset_layout.addWidget(self.override_check, 2, 2)
return group
# === 描述设置 ===
desc_group = QtWidgets.QWidget()
desc_layout = QtWidgets.QGridLayout(desc_group)
desc_layout.setContentsMargins(0, 0, 0, 0)
desc_layout.setSpacing(4)
def _create_layer_settings(self):
"""创建数据分层设置组"""
# === Widget ===
group = QtWidgets.QGroupBox("数据分层")
# 设置列的拉伸因子,使左右两侧均等
desc_layout.setColumnStretch(0, 0) # 左侧标签不拉伸
desc_layout.setColumnStretch(1, 1) # 左侧控件拉伸
desc_layout.setColumnStretch(2, 0) # 右侧标签不拉伸
desc_layout.setColumnStretch(3, 1) # 右侧控件拉伸
# === Layout ===
layout = QtWidgets.QVBoxLayout(group)
layout.setContentsMargins(5, 5, 5, 5)
layout.setSpacing(5)
# 左侧设置
left_settings = [
("名称:", "Archetype", "line"),
("原型:", "其他", "combo"),
("性别:", "女性", "combo"),
("年龄:", "24", "spin")
]
self.behavior_check = QtWidgets.QCheckBox("行为(包括描述和定义)")
self.expression_check = QtWidgets.QCheckBox("覆盖表情选项")
# 右侧设置
right_settings = [
("变换单位:", "厘米", "combo"),
("旋转单位:", "角度", "combo"),
("向上轴:", "Z轴向上", "combo"),
("LOD计数:", "8", "spin")
]
layout.addWidget(self.behavior_check)
layout.addWidget(self.expression_check)
# 添加左侧设置
for row, (label_text, default_value, control_type) in enumerate(left_settings):
label = QtWidgets.QLabel(label_text)
label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) # 标签左对齐
label.setFixedWidth(50) # 固定标签宽度
return group
if control_type == "line":
control = QtWidgets.QLineEdit(default_value)
elif control_type == "combo":
control = QtWidgets.QComboBox()
control.addItem(default_value)
elif control_type == "spin":
control = QtWidgets.QSpinBox()
control.setValue(int(default_value))
def _create_description_settings(self):
"""创建描述设置组"""
# === Widget ===
group = QtWidgets.QGroupBox("描述设置")
desc_layout.addWidget(label, row, 0)
desc_layout.addWidget(control, row, 1)
# === Layout ===
layout = QtWidgets.QFormLayout(group)
layout.setContentsMargins(5, 5, 5, 5)
layout.setSpacing(5)
# 添加右侧设置
for row, (label_text, default_value, control_type) in enumerate(right_settings):
label = QtWidgets.QLabel(label_text)
label.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) # 标签左对齐
label.setFixedWidth(70) # 固定标签宽度,右侧标签略宽
# 创建设置项
self.name_edit = QtWidgets.QLineEdit("Archetype")
self.type_combo = QtWidgets.QComboBox()
self.type_combo.addItem("其他")
self.gender_combo = QtWidgets.QComboBox()
self.gender_combo.addItem("女性")
self.age_spin = QtWidgets.QSpinBox()
self.age_spin.setValue(24)
self.transform_combo = QtWidgets.QComboBox()
self.transform_combo.addItem("厘米")
self.rotation_combo = QtWidgets.QComboBox()
self.rotation_combo.addItem("角度")
self.up_axis_combo = QtWidgets.QComboBox()
self.up_axis_combo.addItem("Z轴向上")
self.lod_spin = QtWidgets.QSpinBox()
self.lod_spin.setValue(8)
if control_type == "line":
control = QtWidgets.QLineEdit(default_value)
elif control_type == "combo":
control = QtWidgets.QComboBox()
control.addItem(default_value)
elif control_type == "spin":
control = QtWidgets.QSpinBox()
control.setValue(int(default_value))
# 添加到布局
layout.addRow("名称:", self.name_edit)
layout.addRow("原型:", self.type_combo)
layout.addRow("性别:", self.gender_combo)
layout.addRow("年龄:", self.age_spin)
layout.addRow("变换单位:", self.transform_combo)
layout.addRow("旋转单位:", self.rotation_combo)
layout.addRow("向上轴标:", self.up_axis_combo)
layout.addRow("LOD计数:", self.lod_spin)
desc_layout.addWidget(label, row, 2)
desc_layout.addWidget(control, row, 3)
return group
# 设置列间距
desc_layout.setHorizontalSpacing(8) # 增加列之间的间距
# === 底部按钮 ===
button_group = QtWidgets.QWidget()
button_layout = QtWidgets.QHBoxLayout(button_group)
button_layout.setContentsMargins(8, 4, 8, 4)
button_layout.setSpacing(4) # 减小按钮间距
# 创建功能按钮
self.clear_btn = self._create_tool_button("清空选项", "delete.png", "delete.png")
self.import_btn = self._create_tool_button("导入骨架", "HIKCharacterToolSkeleton.png", "kinJoint.png")
self.create_btn = self._create_tool_button("创建骨架", "HIKcreateControlRig.png", "kinHandle.png")
# 设置按钮的大小策略
for btn in [self.clear_btn, self.import_btn, self.create_btn]:
btn.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
btn.setMinimumHeight(32)
button_layout.addWidget(btn)
if btn != self.create_btn:
button_layout.addSpacing(4)
# === 添加到主设置布局 ===
settings_layout.addWidget(asset_group)
settings_layout.addWidget(desc_group)
settings_layout.addStretch()
settings_layout.addWidget(button_group)
# === 添加到主布局 ===
self.main_layout.addWidget(self.preview_area, stretch=1)
self.main_layout.addWidget(self.settings_area)
# === 设置样式 ===
self._setup_style()
def _create_preview_area(self):
"""创建DNA预览区域"""
widget = QtWidgets.QWidget()
layout = QtWidgets.QVBoxLayout(widget)
layout.setContentsMargins(0, 0, 0, 0)
layout.setSpacing(0)
# 预览区域 - 单个大框
preview_widget = QtWidgets.QFrame()
preview_widget.setStyleSheet("""
QFrame {
background: #1D1D1D;
border: 1px solid #555555;
}
""")
preview_widget.setMinimumHeight(300) # 调整预览区域高度
# 底部控制区域
control_widget = QtWidgets.QWidget()
control_layout = QtWidgets.QHBoxLayout(control_widget)
control_layout.setContentsMargins(8, 4, 8, 4)
control_layout.setSpacing(8)
# 左侧数值显示和滑块
value_widget = QtWidgets.QWidget()
value_layout = QtWidgets.QHBoxLayout(value_widget)
value_layout.setContentsMargins(0, 0, 0, 0)
value_layout.setSpacing(4)
self.scale_value = QtWidgets.QLabel("90")
self.scale_value.setFixedWidth(30)
self.scale_value.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
self.scale_slider = QtWidgets.QSlider(QtCore.Qt.Horizontal)
self.scale_slider.setRange(0, 100)
self.scale_slider.setValue(90)
self.scale_slider.valueChanged.connect(self._on_scale_changed) # 添加滑块值变化事件
value_layout.addWidget(self.scale_value)
value_layout.addWidget(self.scale_slider)
# 右侧按钮
self.export_btn = QtWidgets.QPushButton("导出预设")
self.export_btn.setIcon(QtGui.QIcon(":save.png")) # 使用Maya内置图标
self.export_btn.setFixedHeight(24)
self.export_btn.setMinimumWidth(80) # 设置最小宽度
self.import_btn = QtWidgets.QPushButton("导入预设")
self.import_btn.setIcon(QtGui.QIcon(":fileOpen.png")) # 使用Maya内置图标
self.import_btn.setFixedHeight(24)
self.import_btn.setMinimumWidth(80) # 设置最小宽度
# 添加到控制布局
# 设置这行高度
control_layout.setContentsMargins(0, 0, 0, 0)
control_layout.setSpacing(4)
control_layout.addWidget(value_widget)
control_layout.addWidget(self.export_btn)
control_layout.addWidget(self.import_btn)
# 添加到主布局
layout.addWidget(preview_widget)
layout.addWidget(control_widget)
return widget
def _create_tool_button(self, text, icon_name, fallback_icon=None):
"""创建工具按钮"""
btn = QtWidgets.QPushButton(text)
# 尝试使用自定义图标如果失败则使用Maya内置图标
icon_path = f"{config.ICONS_PATH}/{icon_name}"
if os.path.exists(icon_path):
btn.setIcon(QtGui.QIcon(icon_path))
elif fallback_icon:
btn.setIcon(QtGui.QIcon(f":{fallback_icon}"))
return btn
def _setup_style(self):
"""设置样式"""
self.setStyleSheet("""
QWidget {
background: #2D2D2D;
color: #CCCCCC;
}
QLabel {
background: transparent;
}
QLineEdit, QComboBox {
background: #3D3D3D;
border: 1px solid #555555;
border-radius: 2px;
padding: 4px;
color: #CCCCCC;
min-height: 22px;
}
QPushButton {
background: #3D3D3D;
border: 1px solid #555555;
border-radius: 2px;
padding: 4px 8px;
color: #CCCCCC;
}
QPushButton:hover {
background: #454545;
}
QPushButton:pressed {
background: #2A2A2A;
}
QCheckBox {
spacing: 8px;
background: transparent;
}
QCheckBox::indicator {
width: 16px;
height: 16px;
}
QSlider::groove:horizontal {
border: 1px solid #555555;
height: 4px;
background: #3D3D3D;
margin: 0px;
border-radius: 2px;
}
QSlider::handle:horizontal {
background: #CCCCCC;
border: 1px solid #555555;
width: 12px;
height: 12px;
margin: -4px 0;
border-radius: 6px;
}
QSlider::handle:horizontal:hover {
background: #FFFFFF;
}
""")
def _on_scale_changed(self, value):
"""滑块值变化事件处理"""
self.scale_value.setText(str(value))
def _create_connections(self):
"""创建信号连接"""
# 缩放滑块
self.zoom_slider.valueChanged.connect(self._on_zoom_changed)
# 导入导出按钮
self.import_btn.clicked.connect(self._on_import)
self.export_btn.clicked.connect(self._on_export)
# 浏览按钮
self.browse_project_btn.clicked.connect(self._on_browse_project)
self.browse_preset_btn.clicked.connect(self._on_browse_preset)
def _on_zoom_changed(self, value):
"""缩放值改变"""
self.zoom_value_label.setText(str(value))
self.preset_view.setIconSize(QtCore.QSize(value, value))
def _on_import(self):
"""导入设置"""
# TODO: 实现导入逻辑
pass
def _on_export(self):
"""导出设置"""
# TODO: 实现导出逻辑
pass
def _on_browse_project(self):
"""浏览项目路径"""
# TODO: 实现浏览逻辑
pass
def _on_browse_preset(self):
"""浏览预设文件"""
# TODO: 实现浏览逻辑
# 滑块值变化事件
self.scale_slider.valueChanged.connect(self._on_scale_changed)
# TODO: 添加信号连接
pass
if __name__ == "__main__":