Base
This commit is contained in:
2156
scripts/ui/Qt.py
Normal file
2156
scripts/ui/Qt.py
Normal file
File diff suppressed because it is too large
Load Diff
4
scripts/ui/__init__.py
Normal file
4
scripts/ui/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import *
|
233
scripts/ui/behaviour.py
Normal file
233
scripts/ui/behaviour.py
Normal file
@@ -0,0 +1,233 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Behaviour UI Module for Plugin
|
||||
行为系统UI模块 - 负责显示角色行为编辑界面和基础操作
|
||||
基本功能:
|
||||
- Blendshape自动加载,刷新,筛选
|
||||
- 次级Blendshape自动加载,刷新,筛选
|
||||
- Blendshape批量导出和导入
|
||||
- Blendshape范围编辑
|
||||
- Blendshape镜像
|
||||
- Blendshape查找翻转目标
|
||||
- Blendshape重建
|
||||
- 表情控制器还原默认表情
|
||||
- 查找选择表情
|
||||
- 控制面板查找
|
||||
- 选择关联关节
|
||||
- 写入当前表情
|
||||
- 写入镜像表情
|
||||
"""
|
||||
|
||||
#===================================== IMPORT MODULES =====================================
|
||||
from Qt import QtWidgets, QtCore, QtGui
|
||||
from Qt.QtCompat import wrapInstance
|
||||
from maya import OpenMayaUI as omui
|
||||
import sys
|
||||
import os
|
||||
|
||||
#===================================== IMPORT FUNCTIONS ===================================
|
||||
from scripts.utils import utils_behaviour as utils_behaviour
|
||||
from scripts.ui import ui_utils
|
||||
|
||||
#========================================== WIDGETS ==========================================
|
||||
# 全局变量存储UI控件
|
||||
blendshape_tree = None
|
||||
sub_blendshape_tree = None
|
||||
blendshape_slider = None
|
||||
blendshape_preview = None
|
||||
behaviour_buttons = {}
|
||||
|
||||
def widgets():
|
||||
"""
|
||||
创建行为系统UI控件
|
||||
"""
|
||||
global blendshape_tree, sub_blendshape_tree, blendshape_slider, blendshape_preview, behaviour_buttons
|
||||
|
||||
# 混合变形树形视图
|
||||
blendshape_tree = QtWidgets.QTreeWidget()
|
||||
blendshape_tree.setHeaderLabels(["混合变形名称", "权重", "类型"])
|
||||
blendshape_tree.setMinimumHeight(200)
|
||||
blendshape_tree.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
|
||||
blendshape_tree.header().setSectionResizeMode(QtWidgets.QHeaderView.Stretch) # 列自动拉伸
|
||||
|
||||
# 次级混合变形树形视图
|
||||
sub_blendshape_tree = QtWidgets.QTreeWidget()
|
||||
sub_blendshape_tree.setHeaderLabels(["次级混合变形", "权重", "目标"])
|
||||
sub_blendshape_tree.setMinimumHeight(150)
|
||||
sub_blendshape_tree.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
|
||||
sub_blendshape_tree.header().setSectionResizeMode(QtWidgets.QHeaderView.Stretch) # 列自动拉伸
|
||||
|
||||
# 混合变形滑块
|
||||
blendshape_slider = QtWidgets.QSlider(QtCore.Qt.Horizontal)
|
||||
blendshape_slider.setMinimum(0)
|
||||
blendshape_slider.setMaximum(100)
|
||||
blendshape_slider.setValue(0)
|
||||
blendshape_slider.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
|
||||
|
||||
# 预览区域
|
||||
blendshape_preview = QtWidgets.QLabel("预览区域")
|
||||
blendshape_preview.setAlignment(QtCore.Qt.AlignCenter)
|
||||
blendshape_preview.setStyleSheet("background-color: #333333; color: white;")
|
||||
blendshape_preview.setMinimumHeight(150)
|
||||
blendshape_preview.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
|
||||
|
||||
# 功能按钮 - 设置统一的大小策略
|
||||
button_names = [
|
||||
"refresh_blendshapes", "refresh_sub_blendshapes", "export_blendshapes", "import_blendshapes",
|
||||
"edit_range", "mirror_blendshape", "find_flip_target", "rebuild_blendshape",
|
||||
"reset_controller", "find_expression", "find_control_panel", "select_related_joints",
|
||||
"write_current_expression", "write_mirror_expression"
|
||||
]
|
||||
|
||||
button_texts = {
|
||||
"refresh_blendshapes": "刷新混合变形",
|
||||
"refresh_sub_blendshapes": "刷新次级混合变形",
|
||||
"export_blendshapes": "导出混合变形",
|
||||
"import_blendshapes": "导入混合变形",
|
||||
"edit_range": "范围编辑",
|
||||
"mirror_blendshape": "混合变形镜像",
|
||||
"find_flip_target": "查找翻转目标",
|
||||
"rebuild_blendshape": "重建混合变形",
|
||||
"reset_controller": "还原默认表情",
|
||||
"find_expression": "查找选择表情",
|
||||
"find_control_panel": "控制面板查找",
|
||||
"select_related_joints": "选择关联关节",
|
||||
"write_current_expression": "写入当前表情",
|
||||
"write_mirror_expression": "写入镜像表情"
|
||||
}
|
||||
|
||||
for button_name in button_names:
|
||||
behaviour_buttons[button_name] = QtWidgets.QPushButton(button_texts[button_name])
|
||||
behaviour_buttons[button_name].setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
|
||||
behaviour_buttons[button_name].setMinimumWidth(120)
|
||||
|
||||
#========================================== LAYOUTS ==========================================
|
||||
def layouts(parent_tab=None):
|
||||
"""
|
||||
创建行为系统UI布局
|
||||
|
||||
Args:
|
||||
parent_tab: 父容器控件,由Main.py传入
|
||||
"""
|
||||
# 获取父容器(在Main.py中创建的behaviour_tab)
|
||||
if not parent_tab:
|
||||
parent_tab = ui_utils.get_parent_widget("behaviour_tab")
|
||||
if not parent_tab:
|
||||
print("无法获取父容器,布局创建失败")
|
||||
return
|
||||
|
||||
# 创建主布局
|
||||
main_layout = parent_tab.layout()
|
||||
if not main_layout:
|
||||
main_layout = QtWidgets.QVBoxLayout(parent_tab)
|
||||
main_layout.setContentsMargins(4, 4, 4, 4)
|
||||
main_layout.setSpacing(4)
|
||||
main_layout.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint) # 设置布局约束为默认,允许自适应
|
||||
|
||||
# 创建主分割控件
|
||||
main_splitter = QtWidgets.QSplitter(QtCore.Qt.Horizontal)
|
||||
|
||||
# 左侧区域 - 混合变形列表
|
||||
left_widget = QtWidgets.QWidget()
|
||||
left_layout = QtWidgets.QVBoxLayout(left_widget)
|
||||
left_layout.setContentsMargins(2, 2, 2, 2)
|
||||
|
||||
# 混合变形列表区域
|
||||
blendshape_group = QtWidgets.QGroupBox("混合变形列表")
|
||||
blendshape_layout = QtWidgets.QVBoxLayout(blendshape_group)
|
||||
|
||||
# 添加刷新按钮
|
||||
refresh_layout = QtWidgets.QHBoxLayout()
|
||||
refresh_layout.addWidget(behaviour_buttons["refresh_blendshapes"])
|
||||
refresh_layout.addWidget(behaviour_buttons["refresh_sub_blendshapes"])
|
||||
blendshape_layout.addLayout(refresh_layout)
|
||||
|
||||
# 创建列表分割控件
|
||||
list_splitter = QtWidgets.QSplitter(QtCore.Qt.Vertical)
|
||||
list_splitter.addWidget(blendshape_tree)
|
||||
list_splitter.addWidget(sub_blendshape_tree)
|
||||
blendshape_layout.addWidget(list_splitter)
|
||||
|
||||
# 添加滑块
|
||||
slider_layout = QtWidgets.QHBoxLayout()
|
||||
slider_layout.addWidget(QtWidgets.QLabel("权重:"))
|
||||
slider_layout.addWidget(blendshape_slider)
|
||||
slider_layout.addWidget(QtWidgets.QLabel("0"))
|
||||
blendshape_layout.addLayout(slider_layout)
|
||||
|
||||
left_layout.addWidget(blendshape_group)
|
||||
|
||||
# 左侧按钮组
|
||||
left_buttons_layout = QtWidgets.QGridLayout()
|
||||
left_buttons_layout.addWidget(behaviour_buttons["export_blendshapes"], 0, 0)
|
||||
left_buttons_layout.addWidget(behaviour_buttons["import_blendshapes"], 0, 1)
|
||||
left_buttons_layout.addWidget(behaviour_buttons["edit_range"], 1, 0)
|
||||
left_buttons_layout.addWidget(behaviour_buttons["mirror_blendshape"], 1, 1)
|
||||
left_buttons_layout.addWidget(behaviour_buttons["find_flip_target"], 2, 0)
|
||||
left_buttons_layout.addWidget(behaviour_buttons["rebuild_blendshape"], 2, 1)
|
||||
left_layout.addLayout(left_buttons_layout)
|
||||
|
||||
# 右侧区域 - 预览和工具
|
||||
right_widget = QtWidgets.QWidget()
|
||||
right_layout = QtWidgets.QVBoxLayout(right_widget)
|
||||
right_layout.setContentsMargins(2, 2, 2, 2)
|
||||
|
||||
# 预览区域
|
||||
preview_group = QtWidgets.QGroupBox("预览")
|
||||
preview_layout = QtWidgets.QVBoxLayout(preview_group)
|
||||
preview_layout.addWidget(blendshape_preview)
|
||||
right_layout.addWidget(preview_group)
|
||||
|
||||
# 右侧按钮组
|
||||
right_buttons_layout = QtWidgets.QGridLayout()
|
||||
right_buttons_layout.addWidget(behaviour_buttons["reset_controller"], 0, 0)
|
||||
right_buttons_layout.addWidget(behaviour_buttons["find_expression"], 0, 1)
|
||||
right_buttons_layout.addWidget(behaviour_buttons["find_control_panel"], 1, 0)
|
||||
right_buttons_layout.addWidget(behaviour_buttons["select_related_joints"], 1, 1)
|
||||
right_buttons_layout.addWidget(behaviour_buttons["write_current_expression"], 2, 0)
|
||||
right_buttons_layout.addWidget(behaviour_buttons["write_mirror_expression"], 2, 1)
|
||||
right_layout.addLayout(right_buttons_layout)
|
||||
|
||||
# 添加到主分割控件
|
||||
main_splitter.addWidget(left_widget)
|
||||
main_splitter.addWidget(right_widget)
|
||||
|
||||
# 设置分割比例
|
||||
main_splitter.setSizes([int(parent_tab.width() * 0.6), int(parent_tab.width() * 0.4)])
|
||||
|
||||
# 添加到主布局
|
||||
main_layout.addWidget(main_splitter)
|
||||
|
||||
#========================================== CONNECTIONS ==========================================
|
||||
def connections():
|
||||
"""
|
||||
连接行为系统UI信号和槽
|
||||
"""
|
||||
# 连接按钮点击事件到占位函数
|
||||
behaviour_buttons["refresh_blendshapes"].clicked.connect(lambda: print("刷新混合变形功能待实现"))
|
||||
behaviour_buttons["refresh_sub_blendshapes"].clicked.connect(lambda: print("刷新次级混合变形功能待实现"))
|
||||
behaviour_buttons["export_blendshapes"].clicked.connect(lambda: print("导出混合变形功能待实现"))
|
||||
behaviour_buttons["import_blendshapes"].clicked.connect(lambda: print("导入混合变形功能待实现"))
|
||||
behaviour_buttons["edit_range"].clicked.connect(lambda: print("范围编辑功能待实现"))
|
||||
behaviour_buttons["mirror_blendshape"].clicked.connect(lambda: print("混合变形镜像功能待实现"))
|
||||
behaviour_buttons["find_flip_target"].clicked.connect(lambda: print("查找翻转目标功能待实现"))
|
||||
behaviour_buttons["rebuild_blendshape"].clicked.connect(lambda: print("重建混合变形功能待实现"))
|
||||
behaviour_buttons["reset_controller"].clicked.connect(lambda: print("还原默认表情功能待实现"))
|
||||
behaviour_buttons["find_expression"].clicked.connect(lambda: print("查找选择表情功能待实现"))
|
||||
behaviour_buttons["find_control_panel"].clicked.connect(lambda: print("控制面板查找功能待实现"))
|
||||
behaviour_buttons["select_related_joints"].clicked.connect(lambda: print("选择关联关节功能待实现"))
|
||||
behaviour_buttons["write_current_expression"].clicked.connect(lambda: print("写入当前表情功能待实现"))
|
||||
behaviour_buttons["write_mirror_expression"].clicked.connect(lambda: print("写入镜像表情功能待实现"))
|
||||
|
||||
# 连接树形视图选择事件
|
||||
blendshape_tree.itemSelectionChanged.connect(lambda: print("混合变形选择已更改"))
|
||||
sub_blendshape_tree.itemSelectionChanged.connect(lambda: print("次级混合变形选择已更改"))
|
||||
|
||||
# 连接滑块值变化事件
|
||||
blendshape_slider.valueChanged.connect(lambda value: print(f"混合变形权重已更改为: {value/100.0}"))
|
||||
|
||||
#===================================== PLACEHOLDER FUNCTION ===================================
|
||||
def behaviour_temp_function():
|
||||
return utils_behaviour.behaviour_temp_utils_function()
|
197
scripts/ui/definition.py
Normal file
197
scripts/ui/definition.py
Normal file
@@ -0,0 +1,197 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Definition UI Module for Plugin
|
||||
定义系统UI模块 - 负责显示DNA定义编辑界面和基础操作
|
||||
基本功能:
|
||||
- LOD, Meshes, Joints, Blendshape, AnimatedMap 加载和刷新
|
||||
- 写入: 写入关节默认位置,写入几何体,写入蒙皮,写入混合变形目标
|
||||
- 创建:创建混合变形,绑定蒙皮,取消蒙皮
|
||||
- 工具:重新定位头部关节,重新定位身体关节,重新定位全身关节,快速创建预设
|
||||
"""
|
||||
|
||||
#===================================== IMPORT MODULES =====================================
|
||||
from Qt import QtWidgets, QtCore, QtGui
|
||||
from Qt.QtCompat import wrapInstance
|
||||
from maya import OpenMayaUI as omui
|
||||
import sys
|
||||
import os
|
||||
|
||||
#===================================== IMPORT FUNCTIONS ===================================
|
||||
from scripts.utils import utils_definition as utils_definition
|
||||
from scripts.ui import ui_utils
|
||||
|
||||
#========================================== WIDGETS ==========================================
|
||||
# 全局变量存储UI控件
|
||||
definition_tabs = None
|
||||
dna_elements = {}
|
||||
definition_buttons = {}
|
||||
|
||||
def widgets():
|
||||
"""
|
||||
创建定义系统UI控件
|
||||
"""
|
||||
global definition_tabs, dna_elements, definition_buttons
|
||||
|
||||
# 创建子标签页
|
||||
definition_tabs = QtWidgets.QTabWidget()
|
||||
|
||||
# 创建各类元素列表
|
||||
dna_elements["lod_list"] = QtWidgets.QListWidget()
|
||||
dna_elements["mesh_list"] = QtWidgets.QListWidget()
|
||||
dna_elements["joint_list"] = QtWidgets.QListWidget()
|
||||
dna_elements["blendshape_list"] = QtWidgets.QListWidget()
|
||||
dna_elements["animmap_list"] = QtWidgets.QListWidget()
|
||||
|
||||
# 创建元素信息面板
|
||||
dna_elements["element_info"] = QtWidgets.QTextEdit()
|
||||
dna_elements["element_info"].setReadOnly(True)
|
||||
|
||||
# 功能按钮
|
||||
definition_buttons["write_joint_defaults"] = QtWidgets.QPushButton("写入关节默认位置")
|
||||
definition_buttons["write_geometry"] = QtWidgets.QPushButton("写入几何体")
|
||||
definition_buttons["write_skinning"] = QtWidgets.QPushButton("写入蒙皮")
|
||||
definition_buttons["write_blendshapes"] = QtWidgets.QPushButton("写入混合变形目标")
|
||||
definition_buttons["create_blendshapes"] = QtWidgets.QPushButton("创建混合变形")
|
||||
definition_buttons["bind_skin"] = QtWidgets.QPushButton("绑定蒙皮")
|
||||
definition_buttons["unbind_skin"] = QtWidgets.QPushButton("取消蒙皮")
|
||||
definition_buttons["reposition_head"] = QtWidgets.QPushButton("重新定位头部关节")
|
||||
definition_buttons["reposition_body"] = QtWidgets.QPushButton("重新定位身体关节")
|
||||
definition_buttons["reposition_all"] = QtWidgets.QPushButton("重新定位全身关节")
|
||||
definition_buttons["quick_preset"] = QtWidgets.QPushButton("快速创建预设")
|
||||
|
||||
#========================================== 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
|
||||
|
||||
# 创建元素标签页
|
||||
elements_tab = QtWidgets.QWidget()
|
||||
elements_layout = QtWidgets.QVBoxLayout(elements_tab)
|
||||
|
||||
# 创建分割控件
|
||||
elements_splitter = QtWidgets.QSplitter(QtCore.Qt.Vertical)
|
||||
|
||||
# 创建元素列表标签页
|
||||
lists_tabs = QtWidgets.QTabWidget()
|
||||
|
||||
# 创建各类元素列表标签页
|
||||
lod_tab = QtWidgets.QWidget()
|
||||
lod_layout = QtWidgets.QVBoxLayout(lod_tab)
|
||||
lod_layout.addWidget(dna_elements["lod_list"])
|
||||
lists_tabs.addTab(lod_tab, "LOD")
|
||||
|
||||
mesh_tab = QtWidgets.QWidget()
|
||||
mesh_layout = QtWidgets.QVBoxLayout(mesh_tab)
|
||||
mesh_layout.addWidget(dna_elements["mesh_list"])
|
||||
lists_tabs.addTab(mesh_tab, "Meshes")
|
||||
|
||||
joint_tab = QtWidgets.QWidget()
|
||||
joint_layout = QtWidgets.QVBoxLayout(joint_tab)
|
||||
joint_layout.addWidget(dna_elements["joint_list"])
|
||||
lists_tabs.addTab(joint_tab, "Joints")
|
||||
|
||||
blendshape_tab = QtWidgets.QWidget()
|
||||
blendshape_layout = QtWidgets.QVBoxLayout(blendshape_tab)
|
||||
blendshape_layout.addWidget(dna_elements["blendshape_list"])
|
||||
lists_tabs.addTab(blendshape_tab, "Blendshapes")
|
||||
|
||||
animmap_tab = QtWidgets.QWidget()
|
||||
animmap_layout = QtWidgets.QVBoxLayout(animmap_tab)
|
||||
animmap_layout.addWidget(dna_elements["animmap_list"])
|
||||
lists_tabs.addTab(animmap_tab, "AnimatedMaps")
|
||||
|
||||
# 信息面板
|
||||
info_group = QtWidgets.QGroupBox("元素信息")
|
||||
info_layout = QtWidgets.QVBoxLayout(info_group)
|
||||
info_layout.addWidget(dna_elements["element_info"])
|
||||
|
||||
# 添加到分割控件
|
||||
elements_splitter.addWidget(lists_tabs)
|
||||
elements_splitter.addWidget(info_group)
|
||||
elements_layout.addWidget(elements_splitter)
|
||||
|
||||
# 创建工具标签页
|
||||
tools_tab = QtWidgets.QWidget()
|
||||
tools_layout = QtWidgets.QVBoxLayout(tools_tab)
|
||||
|
||||
# 创建工具分组
|
||||
write_group = QtWidgets.QGroupBox("写入")
|
||||
write_layout = QtWidgets.QVBoxLayout(write_group)
|
||||
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"])
|
||||
|
||||
create_group = QtWidgets.QGroupBox("创建")
|
||||
create_layout = QtWidgets.QVBoxLayout(create_group)
|
||||
create_layout.addWidget(definition_buttons["create_blendshapes"])
|
||||
create_layout.addWidget(definition_buttons["bind_skin"])
|
||||
create_layout.addWidget(definition_buttons["unbind_skin"])
|
||||
|
||||
tools_group = QtWidgets.QGroupBox("工具")
|
||||
tools_layout2 = QtWidgets.QVBoxLayout(tools_group)
|
||||
tools_layout2.addWidget(definition_buttons["reposition_head"])
|
||||
tools_layout2.addWidget(definition_buttons["reposition_body"])
|
||||
tools_layout2.addWidget(definition_buttons["reposition_all"])
|
||||
tools_layout2.addWidget(definition_buttons["quick_preset"])
|
||||
|
||||
# 添加到工具标签页
|
||||
tools_layout.addWidget(write_group)
|
||||
tools_layout.addWidget(create_group)
|
||||
tools_layout.addWidget(tools_group)
|
||||
tools_layout.addStretch()
|
||||
|
||||
# 添加标签页到主标签控件
|
||||
definition_tabs.addTab(elements_tab, "元素")
|
||||
definition_tabs.addTab(tools_tab, "工具")
|
||||
|
||||
# 添加到主布局
|
||||
main_layout.addWidget(definition_tabs)
|
||||
|
||||
#========================================== 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: print(f"{k} 选择已更改"))
|
||||
|
||||
# 连接标签页切换事件
|
||||
definition_tabs.currentChanged.connect(lambda index: print(f"切换到标签页: {definition_tabs.tabText(index)}"))
|
||||
|
||||
#===================================== PLACEHOLDER FUNCTION ===================================
|
||||
def definition_temp_function():
|
||||
utils_definition.definition_temp_utils_function
|
169
scripts/ui/geometry.py
Normal file
169
scripts/ui/geometry.py
Normal file
@@ -0,0 +1,169 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Geometry UI Module for Plugin
|
||||
几何模型UI模块 - 负责显示几何模型编辑界面和基础操作
|
||||
基本功能:
|
||||
- 模型拾取以及加载
|
||||
- LOD模型分级过滤
|
||||
- LOD模型创建
|
||||
- 自动加载模型
|
||||
- 标准化命名
|
||||
- 自动分组
|
||||
- 生成面部配件(睫毛,舌头,泪腺 等)
|
||||
- 修复接缝(修复法线)
|
||||
- 修复点序
|
||||
"""
|
||||
|
||||
#===================================== IMPORT MODULES =====================================
|
||||
from Qt import QtWidgets, QtCore, QtGui
|
||||
from Qt.QtCompat import wrapInstance
|
||||
from maya import OpenMayaUI as omui
|
||||
import sys
|
||||
import os
|
||||
|
||||
#===================================== IMPORT FUNCTIONS ===================================
|
||||
from scripts.utils import utils_geometry as utils_geometry
|
||||
from scripts.ui import ui_utils
|
||||
|
||||
#========================================== WIDGETS ==========================================
|
||||
# 全局变量存储UI控件
|
||||
model_tree = None
|
||||
lod_combo = None
|
||||
model_buttons = {}
|
||||
model_info_panel = None
|
||||
|
||||
def widgets():
|
||||
"""
|
||||
创建几何模型UI控件
|
||||
"""
|
||||
global model_tree, lod_combo, model_buttons, model_info_panel
|
||||
|
||||
# LOD选择下拉菜单
|
||||
lod_combo = QtWidgets.QComboBox()
|
||||
lod_combo.addItems(["LOD0", "LOD1", "LOD2", "LOD3", "LOD4"])
|
||||
lod_combo.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
|
||||
lod_combo.setMinimumWidth(100)
|
||||
|
||||
# 模型树形视图
|
||||
model_tree = QtWidgets.QTreeWidget()
|
||||
model_tree.setHeaderLabels(["模型名称", "顶点数", "面数"])
|
||||
model_tree.setMinimumHeight(250)
|
||||
model_tree.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
|
||||
model_tree.header().setSectionResizeMode(QtWidgets.QHeaderView.Stretch) # 列自动拉伸
|
||||
|
||||
# 模型信息面板
|
||||
model_info_panel = QtWidgets.QTextEdit()
|
||||
model_info_panel.setReadOnly(True)
|
||||
model_info_panel.setMinimumHeight(100)
|
||||
model_info_panel.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
|
||||
|
||||
# 功能按钮 - 设置统一的大小策略
|
||||
for button_name in ["load_model", "create_lod", "auto_load", "standardize_name",
|
||||
"auto_group", "generate_accessories", "fix_seams", "fix_vertex_order"]:
|
||||
model_buttons[button_name] = QtWidgets.QPushButton({
|
||||
"load_model": "加载模型",
|
||||
"create_lod": "创建LOD",
|
||||
"auto_load": "自动加载",
|
||||
"standardize_name": "标准化命名",
|
||||
"auto_group": "自动分组",
|
||||
"generate_accessories": "生成面部配件",
|
||||
"fix_seams": "修复接缝",
|
||||
"fix_vertex_order": "修复点序"
|
||||
}[button_name])
|
||||
model_buttons[button_name].setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
|
||||
model_buttons[button_name].setMinimumWidth(120)
|
||||
|
||||
#========================================== LAYOUTS ==========================================
|
||||
def layouts(parent_tab=None):
|
||||
"""
|
||||
创建几何模型UI布局
|
||||
|
||||
Args:
|
||||
parent_tab: 父容器控件,由Main.py传入
|
||||
"""
|
||||
# 获取父容器(在Main.py中创建的geometry_tab)
|
||||
if not parent_tab:
|
||||
parent_tab = ui_utils.get_parent_widget("geometry_tab")
|
||||
if not parent_tab:
|
||||
print("无法获取父容器,布局创建失败")
|
||||
return
|
||||
|
||||
# 创建主布局
|
||||
main_layout = parent_tab.layout()
|
||||
if not main_layout:
|
||||
main_layout = QtWidgets.QVBoxLayout(parent_tab)
|
||||
main_layout.setContentsMargins(4, 4, 4, 4)
|
||||
main_layout.setSpacing(4)
|
||||
main_layout.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint) # 设置布局约束为默认,允许自适应
|
||||
|
||||
# 创建分割控件
|
||||
splitter = QtWidgets.QSplitter(QtCore.Qt.Vertical)
|
||||
|
||||
# 上部区域 - LOD选择和模型树
|
||||
top_widget = QtWidgets.QWidget()
|
||||
top_layout = QtWidgets.QVBoxLayout(top_widget)
|
||||
top_layout.setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
# LOD选择区域
|
||||
lod_layout = QtWidgets.QHBoxLayout()
|
||||
lod_layout.addWidget(QtWidgets.QLabel("LOD级别:"))
|
||||
lod_layout.addWidget(lod_combo)
|
||||
lod_layout.addStretch()
|
||||
top_layout.addLayout(lod_layout)
|
||||
|
||||
# 模型树区域
|
||||
model_group = QtWidgets.QGroupBox("模型列表")
|
||||
model_layout = QtWidgets.QVBoxLayout(model_group)
|
||||
model_layout.addWidget(model_tree)
|
||||
top_layout.addWidget(model_group)
|
||||
|
||||
# 下部区域 - 模型信息
|
||||
model_info_group = QtWidgets.QGroupBox("模型信息")
|
||||
model_info_layout = QtWidgets.QVBoxLayout(model_info_group)
|
||||
model_info_layout.addWidget(model_info_panel)
|
||||
|
||||
# 添加到分割控件
|
||||
splitter.addWidget(top_widget)
|
||||
splitter.addWidget(model_info_group)
|
||||
|
||||
# 按钮区域
|
||||
button_layout = QtWidgets.QGridLayout()
|
||||
button_layout.addWidget(model_buttons["load_model"], 0, 0)
|
||||
button_layout.addWidget(model_buttons["create_lod"], 0, 1)
|
||||
button_layout.addWidget(model_buttons["auto_load"], 1, 0)
|
||||
button_layout.addWidget(model_buttons["standardize_name"], 1, 1)
|
||||
button_layout.addWidget(model_buttons["auto_group"], 2, 0)
|
||||
button_layout.addWidget(model_buttons["generate_accessories"], 2, 1)
|
||||
button_layout.addWidget(model_buttons["fix_seams"], 3, 0)
|
||||
button_layout.addWidget(model_buttons["fix_vertex_order"], 3, 1)
|
||||
|
||||
# 添加到主布局
|
||||
main_layout.addWidget(splitter)
|
||||
main_layout.addLayout(button_layout)
|
||||
|
||||
#========================================== CONNECTIONS ==========================================
|
||||
def connections():
|
||||
"""
|
||||
连接几何模型UI信号和槽
|
||||
"""
|
||||
# 连接按钮点击事件到占位函数
|
||||
model_buttons["load_model"].clicked.connect(lambda: print("加载模型功能待实现"))
|
||||
model_buttons["create_lod"].clicked.connect(lambda: print("创建LOD功能待实现"))
|
||||
model_buttons["auto_load"].clicked.connect(lambda: print("自动加载功能待实现"))
|
||||
model_buttons["standardize_name"].clicked.connect(lambda: print("标准化命名功能待实现"))
|
||||
model_buttons["auto_group"].clicked.connect(lambda: print("自动分组功能待实现"))
|
||||
model_buttons["generate_accessories"].clicked.connect(lambda: print("生成面部配件功能待实现"))
|
||||
model_buttons["fix_seams"].clicked.connect(lambda: print("修复接缝功能待实现"))
|
||||
model_buttons["fix_vertex_order"].clicked.connect(lambda: print("修复点序功能待实现"))
|
||||
|
||||
# 连接LOD选择事件
|
||||
lod_combo.currentIndexChanged.connect(lambda index: print(f"选择的LOD级别: {lod_combo.currentText()}"))
|
||||
|
||||
# 连接模型树选择事件
|
||||
model_tree.itemSelectionChanged.connect(lambda: print("模型选择已更改"))
|
||||
|
||||
#===================================== PLACEHOLDER FUNCTION ===================================
|
||||
def geometry_temp_function():
|
||||
return utils_geometry.geometry_temp_utils_function()
|
12
scripts/ui/localization.py
Normal file
12
scripts/ui/localization.py
Normal file
@@ -0,0 +1,12 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Localization module
|
||||
"""
|
||||
LANG = {
|
||||
"en_US": {
|
||||
},
|
||||
"zh_CN": {
|
||||
}
|
||||
}
|
147
scripts/ui/rigging.py
Normal file
147
scripts/ui/rigging.py
Normal file
@@ -0,0 +1,147 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Rigging UI Module for Plugin
|
||||
绑定系统UI模块 - 负责显示骨骼绑定编辑界面和基础操作
|
||||
基本功能:
|
||||
- DNA浏览器
|
||||
- 根据DNA导入骨骼
|
||||
- 根据DNA生成身体
|
||||
- DNA校准
|
||||
- 骨骼位置校准
|
||||
- 创建绑定
|
||||
- 复制蒙皮
|
||||
"""
|
||||
|
||||
#===================================== IMPORT MODULES =====================================
|
||||
from Qt import QtWidgets, QtCore, QtGui
|
||||
from Qt.QtCompat import wrapInstance
|
||||
from maya import OpenMayaUI as omui
|
||||
import sys
|
||||
import os
|
||||
|
||||
#===================================== IMPORT FUNCTIONS ===================================
|
||||
from scripts.utils import utils_rigging as utils_rigging
|
||||
from scripts.ui import ui_utils
|
||||
|
||||
#========================================== WIDGETS ==========================================
|
||||
# 全局变量存储UI控件
|
||||
dna_browser_tree = None
|
||||
joint_list = None
|
||||
dna_info_panel = None
|
||||
rig_buttons = {}
|
||||
|
||||
def widgets():
|
||||
"""
|
||||
创建绑定系统UI控件
|
||||
"""
|
||||
global dna_browser_tree, joint_list, dna_info_panel, rig_buttons
|
||||
|
||||
# DNA浏览器树形视图
|
||||
dna_browser_tree = QtWidgets.QTreeWidget()
|
||||
dna_browser_tree.setHeaderLabels(["DNA文件", "版本", "修改日期"])
|
||||
dna_browser_tree.setMinimumHeight(200)
|
||||
|
||||
# 关节列表
|
||||
joint_list = QtWidgets.QListWidget()
|
||||
joint_list.setMinimumHeight(150)
|
||||
|
||||
# DNA信息面板
|
||||
dna_info_panel = QtWidgets.QTextEdit()
|
||||
dna_info_panel.setReadOnly(True)
|
||||
dna_info_panel.setMinimumHeight(100)
|
||||
|
||||
# 功能按钮
|
||||
rig_buttons["load_dna"] = QtWidgets.QPushButton("加载DNA")
|
||||
rig_buttons["import_joints"] = QtWidgets.QPushButton("导入骨骼")
|
||||
rig_buttons["generate_body"] = QtWidgets.QPushButton("生成身体")
|
||||
rig_buttons["calibrate_dna"] = QtWidgets.QPushButton("DNA校准")
|
||||
rig_buttons["calibrate_joints"] = QtWidgets.QPushButton("骨骼位置校准")
|
||||
rig_buttons["create_binding"] = QtWidgets.QPushButton("创建绑定")
|
||||
rig_buttons["copy_skinning"] = QtWidgets.QPushButton("复制蒙皮")
|
||||
rig_buttons["save_dna"] = QtWidgets.QPushButton("保存DNA")
|
||||
|
||||
#========================================== LAYOUTS ==========================================
|
||||
def layouts(parent_tab=None):
|
||||
"""
|
||||
创建绑定系统UI布局
|
||||
|
||||
Args:
|
||||
parent_tab: 父容器控件,由Main.py传入
|
||||
"""
|
||||
# 获取父容器(在Main.py中创建的rigging_tab)
|
||||
if not parent_tab:
|
||||
parent_tab = ui_utils.get_parent_widget("rigging_tab")
|
||||
if not parent_tab:
|
||||
print("无法获取父容器,布局创建失败")
|
||||
return
|
||||
|
||||
# 创建主布局
|
||||
main_layout = parent_tab.layout()
|
||||
if not main_layout:
|
||||
print("父容器没有布局,布局创建失败")
|
||||
return
|
||||
|
||||
# 创建分割控件
|
||||
splitter = QtWidgets.QSplitter(QtCore.Qt.Vertical)
|
||||
|
||||
# 上部区域 - DNA浏览器
|
||||
dna_browser_group = QtWidgets.QGroupBox("DNA浏览器")
|
||||
dna_browser_layout = QtWidgets.QVBoxLayout(dna_browser_group)
|
||||
dna_browser_layout.addWidget(dna_browser_tree)
|
||||
|
||||
# 中部区域 - 关节列表
|
||||
joint_list_group = QtWidgets.QGroupBox("骨骼列表")
|
||||
joint_list_layout = QtWidgets.QVBoxLayout(joint_list_group)
|
||||
joint_list_layout.addWidget(joint_list)
|
||||
|
||||
# 下部区域 - DNA信息
|
||||
dna_info_group = QtWidgets.QGroupBox("DNA信息")
|
||||
dna_info_layout = QtWidgets.QVBoxLayout(dna_info_group)
|
||||
dna_info_layout.addWidget(dna_info_panel)
|
||||
|
||||
# 添加到分割控件
|
||||
splitter.addWidget(dna_browser_group)
|
||||
splitter.addWidget(joint_list_group)
|
||||
splitter.addWidget(dna_info_group)
|
||||
|
||||
# 按钮区域
|
||||
button_layout = QtWidgets.QGridLayout()
|
||||
button_layout.addWidget(rig_buttons["load_dna"], 0, 0)
|
||||
button_layout.addWidget(rig_buttons["import_joints"], 0, 1)
|
||||
button_layout.addWidget(rig_buttons["generate_body"], 1, 0)
|
||||
button_layout.addWidget(rig_buttons["calibrate_dna"], 1, 1)
|
||||
button_layout.addWidget(rig_buttons["calibrate_joints"], 2, 0)
|
||||
button_layout.addWidget(rig_buttons["create_binding"], 2, 1)
|
||||
button_layout.addWidget(rig_buttons["copy_skinning"], 3, 0)
|
||||
button_layout.addWidget(rig_buttons["save_dna"], 3, 1)
|
||||
|
||||
# 添加到主布局
|
||||
main_layout.addWidget(splitter)
|
||||
main_layout.addLayout(button_layout)
|
||||
|
||||
#========================================== CONNECTIONS ==========================================
|
||||
def connections():
|
||||
"""
|
||||
连接绑定系统UI信号和槽
|
||||
"""
|
||||
# 连接按钮点击事件到占位函数
|
||||
rig_buttons["load_dna"].clicked.connect(lambda: print("加载DNA功能待实现"))
|
||||
rig_buttons["import_joints"].clicked.connect(lambda: print("导入骨骼功能待实现"))
|
||||
rig_buttons["generate_body"].clicked.connect(lambda: print("生成身体功能待实现"))
|
||||
rig_buttons["calibrate_dna"].clicked.connect(lambda: print("DNA校准功能待实现"))
|
||||
rig_buttons["calibrate_joints"].clicked.connect(lambda: print("骨骼位置校准功能待实现"))
|
||||
rig_buttons["create_binding"].clicked.connect(lambda: print("创建绑定功能待实现"))
|
||||
rig_buttons["copy_skinning"].clicked.connect(lambda: print("复制蒙皮功能待实现"))
|
||||
rig_buttons["save_dna"].clicked.connect(lambda: print("保存DNA功能待实现"))
|
||||
|
||||
# 连接树形视图选择事件
|
||||
dna_browser_tree.itemSelectionChanged.connect(lambda: print("DNA文件选择已更改"))
|
||||
|
||||
# 连接关节列表选择事件
|
||||
joint_list.itemSelectionChanged.connect(lambda: print("骨骼选择已更改"))
|
||||
|
||||
#===================================== PLACEHOLDER FUNCTION ===================================
|
||||
def rigging_temp_function():
|
||||
return utils_rigging.rigging_temp_utils_function()
|
321
scripts/ui/style.qss
Normal file
321
scripts/ui/style.qss
Normal file
@@ -0,0 +1,321 @@
|
||||
/* Plugin 统一样式表 */
|
||||
|
||||
/* 全局样式 */
|
||||
QWidget {
|
||||
font-family: "Microsoft YaHei", "SimHei", sans-serif;
|
||||
font-size: 9pt;
|
||||
color: #E0E0E0;
|
||||
background-color: #333333;
|
||||
}
|
||||
|
||||
/* 菜单样式 */
|
||||
QMenuBar {
|
||||
background-color: #2D2D30;
|
||||
color: #E0E0E0;
|
||||
}
|
||||
|
||||
QMenuBar::item {
|
||||
background-color: transparent;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
QMenuBar::item:selected {
|
||||
background-color: #007ACC;
|
||||
color: white;
|
||||
}
|
||||
|
||||
QMenu {
|
||||
background-color: #1E1E1E;
|
||||
color: #E0E0E0;
|
||||
border: 1px solid #3F3F46;
|
||||
}
|
||||
|
||||
QMenu::item {
|
||||
padding: 5px 30px 5px 20px;
|
||||
}
|
||||
|
||||
QMenu::item:selected {
|
||||
background-color: #007ACC;
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* 工具栏样式 */
|
||||
QToolBar {
|
||||
background-color: #2D2D30;
|
||||
border: 1px solid #3F3F46;
|
||||
spacing: 3px;
|
||||
}
|
||||
|
||||
QToolBar::separator {
|
||||
background-color: #3F3F46;
|
||||
width: 1px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
/* 标签页样式 */
|
||||
QTabWidget::pane {
|
||||
border: 1px solid #3F3F46;
|
||||
background-color: #2D2D30;
|
||||
}
|
||||
|
||||
QTabBar::tab {
|
||||
background-color: #252526;
|
||||
color: #E0E0E0;
|
||||
border: 1px solid #3F3F46;
|
||||
border-bottom: none;
|
||||
padding: 5px 10px;
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
min-width: 80px;
|
||||
}
|
||||
|
||||
QTabBar::tab:selected {
|
||||
background-color: #007ACC;
|
||||
color: white;
|
||||
}
|
||||
|
||||
QTabBar::tab:hover:!selected {
|
||||
background-color: #3E3E40;
|
||||
}
|
||||
|
||||
/* 分组框样式 */
|
||||
QGroupBox {
|
||||
border: 1px solid #3F3F46;
|
||||
border-radius: 3px;
|
||||
margin-top: 10px;
|
||||
padding-top: 10px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
QGroupBox::title {
|
||||
subcontrol-origin: margin;
|
||||
subcontrol-position: top left;
|
||||
padding: 0 5px;
|
||||
color: #E0E0E0;
|
||||
}
|
||||
|
||||
/* 下拉框样式 */
|
||||
QComboBox {
|
||||
background-color: #1E1E1E;
|
||||
color: #E0E0E0;
|
||||
border: 1px solid #3F3F46;
|
||||
border-radius: 3px;
|
||||
padding: 3px 18px 3px 3px;
|
||||
min-width: 6em;
|
||||
}
|
||||
|
||||
QComboBox::drop-down {
|
||||
subcontrol-origin: padding;
|
||||
subcontrol-position: top right;
|
||||
width: 15px;
|
||||
border-left: 1px solid #3F3F46;
|
||||
}
|
||||
|
||||
QComboBox QAbstractItemView {
|
||||
background-color: #1E1E1E;
|
||||
color: #E0E0E0;
|
||||
border: 1px solid #3F3F46;
|
||||
selection-background-color: #264F78;
|
||||
selection-color: white;
|
||||
}
|
||||
|
||||
/* 按钮样式 */
|
||||
QPushButton {
|
||||
background-color: #0E639C;
|
||||
color: white;
|
||||
border: 1px solid #0E639C;
|
||||
border-radius: 3px;
|
||||
padding: 5px 10px;
|
||||
min-width: 80px;
|
||||
}
|
||||
|
||||
QPushButton:hover {
|
||||
background-color: #1177BB;
|
||||
border: 1px solid #1177BB;
|
||||
}
|
||||
|
||||
QPushButton:pressed {
|
||||
background-color: #00578A;
|
||||
border: 1px solid #00578A;
|
||||
}
|
||||
|
||||
QPushButton:disabled {
|
||||
background-color: #3F3F46;
|
||||
color: #9D9D9D;
|
||||
border: 1px solid #3F3F46;
|
||||
}
|
||||
|
||||
/* 输入框样式 */
|
||||
QLineEdit, QTextEdit, QPlainTextEdit {
|
||||
background-color: #1E1E1E;
|
||||
color: #E0E0E0;
|
||||
border: 1px solid #3F3F46;
|
||||
border-radius: 3px;
|
||||
padding: 3px;
|
||||
selection-background-color: #264F78;
|
||||
}
|
||||
|
||||
/* 单选框样式 */
|
||||
QRadioButton {
|
||||
color: #E0E0E0;
|
||||
spacing: 5px;
|
||||
}
|
||||
|
||||
QRadioButton::indicator {
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
}
|
||||
|
||||
/* 复选框样式 */
|
||||
QCheckBox {
|
||||
color: #E0E0E0;
|
||||
spacing: 5px;
|
||||
}
|
||||
|
||||
QCheckBox::indicator {
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
}
|
||||
|
||||
/* 滑块样式 */
|
||||
QSlider::groove:horizontal {
|
||||
border: 1px solid #3F3F46;
|
||||
height: 8px;
|
||||
background: #1E1E1E;
|
||||
margin: 2px 0;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
QSlider::handle:horizontal {
|
||||
background: #007ACC;
|
||||
border: 1px solid #007ACC;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
margin: -4px 0;
|
||||
border-radius: 7px;
|
||||
}
|
||||
|
||||
QSlider::handle:horizontal:hover {
|
||||
background: #1177BB;
|
||||
border: 1px solid #1177BB;
|
||||
}
|
||||
|
||||
/* 进度条样式 */
|
||||
QProgressBar {
|
||||
border: 1px solid #3F3F46;
|
||||
border-radius: 3px;
|
||||
background-color: #1E1E1E;
|
||||
text-align: center;
|
||||
color: white;
|
||||
}
|
||||
|
||||
QProgressBar::chunk {
|
||||
background-color: #007ACC;
|
||||
width: 10px;
|
||||
}
|
||||
|
||||
/* 列表和树视图样式 */
|
||||
QTreeView, QListView, QTableView {
|
||||
background-color: #1E1E1E;
|
||||
alternate-background-color: #262626;
|
||||
color: #E0E0E0;
|
||||
border: 1px solid #3F3F46;
|
||||
selection-background-color: #264F78;
|
||||
selection-color: white;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
QTreeView::item, QListView::item, QTableView::item {
|
||||
padding: 3px;
|
||||
}
|
||||
|
||||
QTreeView::item:selected, QListView::item:selected, QTableView::item:selected {
|
||||
background-color: #264F78;
|
||||
color: white;
|
||||
}
|
||||
|
||||
QTreeView::item:hover, QListView::item:hover, QTableView::item:hover {
|
||||
background-color: #2A2D2E;
|
||||
}
|
||||
|
||||
QHeaderView::section {
|
||||
background-color: #252526;
|
||||
color: #E0E0E0;
|
||||
padding: 3px;
|
||||
border: 1px solid #3F3F46;
|
||||
}
|
||||
|
||||
/* 滚动条样式 */
|
||||
QScrollBar:vertical {
|
||||
background-color: #1E1E1E;
|
||||
width: 14px;
|
||||
margin: 14px 0 14px 0;
|
||||
border: 1px solid #3F3F46;
|
||||
}
|
||||
|
||||
QScrollBar::handle:vertical {
|
||||
background-color: #3E3E42;
|
||||
min-height: 20px;
|
||||
}
|
||||
|
||||
QScrollBar::add-line:vertical {
|
||||
border: 1px solid #3F3F46;
|
||||
background-color: #3E3E42;
|
||||
height: 14px;
|
||||
subcontrol-position: bottom;
|
||||
subcontrol-origin: margin;
|
||||
}
|
||||
|
||||
QScrollBar::sub-line:vertical {
|
||||
border: 1px solid #3F3F46;
|
||||
background-color: #3E3E42;
|
||||
height: 14px;
|
||||
subcontrol-position: top;
|
||||
subcontrol-origin: margin;
|
||||
}
|
||||
|
||||
QScrollBar:horizontal {
|
||||
background-color: #1E1E1E;
|
||||
height: 14px;
|
||||
margin: 0 14px 0 14px;
|
||||
border: 1px solid #3F3F46;
|
||||
}
|
||||
|
||||
QScrollBar::handle:horizontal {
|
||||
background-color: #3E3E42;
|
||||
min-width: 20px;
|
||||
}
|
||||
|
||||
QScrollBar::add-line:horizontal {
|
||||
border: 1px solid #3F3F46;
|
||||
background-color: #3E3E42;
|
||||
width: 14px;
|
||||
subcontrol-position: right;
|
||||
subcontrol-origin: margin;
|
||||
}
|
||||
|
||||
QScrollBar::sub-line:horizontal {
|
||||
border: 1px solid #3F3F46;
|
||||
background-color: #3E3E42;
|
||||
width: 14px;
|
||||
subcontrol-position: left;
|
||||
subcontrol-origin: margin;
|
||||
}
|
||||
|
||||
/* 状态栏样式 */
|
||||
QStatusBar {
|
||||
background-color: #007ACC;
|
||||
color: white;
|
||||
}
|
||||
|
||||
QStatusBar::item {
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* 提示框样式 */
|
||||
QToolTip {
|
||||
background-color: #2D2D30;
|
||||
color: #E0E0E0;
|
||||
border: 1px solid #3F3F46;
|
||||
padding: 3px;
|
||||
}
|
138
scripts/ui/toolbar.py
Normal file
138
scripts/ui/toolbar.py
Normal file
@@ -0,0 +1,138 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Toolbar UI Module for Plugin
|
||||
工具栏UI模块 - 负责显示工具栏界面和基础操作
|
||||
基本功能:
|
||||
- 加载预设
|
||||
- 保存预设
|
||||
- 导入DNA
|
||||
- 导出DNA
|
||||
- 创建RL4节点(用于切换DNA编辑的状态)
|
||||
- 删除RL4节点(用于切换DNA编辑的状态)
|
||||
"""
|
||||
|
||||
#===================================== IMPORT MODULES =====================================
|
||||
from Qt import QtWidgets, QtCore, QtGui
|
||||
from Qt.QtCompat import wrapInstance
|
||||
from maya import OpenMayaUI as omui
|
||||
import sys
|
||||
import os
|
||||
|
||||
#===================================== IMPORT FUNCTIONS ===================================
|
||||
from scripts.utils import utils_toolbar as utils_toolbar
|
||||
from scripts.ui import ui_utils
|
||||
|
||||
#========================================== WIDGETS ==========================================
|
||||
# 全局变量存储UI控件
|
||||
toolbar_buttons = {}
|
||||
dna_dropdown = None
|
||||
status_label = None
|
||||
|
||||
def widgets():
|
||||
"""
|
||||
创建工具栏UI控件
|
||||
"""
|
||||
global toolbar_buttons, dna_dropdown, status_label
|
||||
|
||||
# 工具栏按钮
|
||||
toolbar_buttons["load_preset"] = QtWidgets.QPushButton("加载预设")
|
||||
toolbar_buttons["load_preset"].setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
|
||||
toolbar_buttons["load_preset"].setMinimumWidth(80)
|
||||
|
||||
toolbar_buttons["save_preset"] = QtWidgets.QPushButton("保存预设")
|
||||
toolbar_buttons["save_preset"].setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
|
||||
toolbar_buttons["save_preset"].setMinimumWidth(80)
|
||||
|
||||
toolbar_buttons["import_dna"] = QtWidgets.QPushButton("导入DNA")
|
||||
toolbar_buttons["import_dna"].setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
|
||||
toolbar_buttons["import_dna"].setMinimumWidth(80)
|
||||
|
||||
toolbar_buttons["export_dna"] = QtWidgets.QPushButton("导出DNA")
|
||||
toolbar_buttons["export_dna"].setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
|
||||
toolbar_buttons["export_dna"].setMinimumWidth(80)
|
||||
|
||||
toolbar_buttons["create_rl4"] = QtWidgets.QPushButton("创建RL4节点")
|
||||
toolbar_buttons["create_rl4"].setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
|
||||
toolbar_buttons["create_rl4"].setMinimumWidth(100)
|
||||
|
||||
toolbar_buttons["delete_rl4"] = QtWidgets.QPushButton("删除RL4节点")
|
||||
toolbar_buttons["delete_rl4"].setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
|
||||
toolbar_buttons["delete_rl4"].setMinimumWidth(100)
|
||||
|
||||
# DNA下拉菜单
|
||||
dna_dropdown = QtWidgets.QComboBox()
|
||||
dna_dropdown.addItem("选择DNA文件...")
|
||||
dna_dropdown.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
|
||||
dna_dropdown.setMinimumWidth(150)
|
||||
|
||||
# 状态标签
|
||||
status_label = QtWidgets.QLabel("就绪")
|
||||
status_label.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
|
||||
status_label.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
|
||||
|
||||
#========================================== LAYOUTS ==========================================
|
||||
def layouts(parent_frame=None):
|
||||
"""
|
||||
创建工具栏UI布局
|
||||
|
||||
Args:
|
||||
parent_frame: 父容器控件,由Main.py传入
|
||||
"""
|
||||
# 获取父容器(在Main.py中创建的toolbar_frame)
|
||||
if not parent_frame:
|
||||
parent_frame = ui_utils.get_parent_widget("toolbar_frame")
|
||||
if not parent_frame:
|
||||
print("无法获取父容器,布局创建失败")
|
||||
return
|
||||
|
||||
# 创建主布局
|
||||
main_layout = parent_frame.layout()
|
||||
if not main_layout:
|
||||
print("父容器没有布局,布局创建失败")
|
||||
return
|
||||
|
||||
# 创建工具栏布局
|
||||
toolbar_layout = QtWidgets.QHBoxLayout()
|
||||
toolbar_layout.setContentsMargins(2, 2, 2, 2)
|
||||
toolbar_layout.setSpacing(4)
|
||||
toolbar_layout.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint) # 设置布局约束为默认,允许自适应
|
||||
|
||||
# 添加按钮到工具栏
|
||||
toolbar_layout.addWidget(toolbar_buttons["load_preset"])
|
||||
toolbar_layout.addWidget(toolbar_buttons["save_preset"])
|
||||
toolbar_layout.addWidget(QtWidgets.QLabel("|"))
|
||||
toolbar_layout.addWidget(toolbar_buttons["import_dna"])
|
||||
toolbar_layout.addWidget(toolbar_buttons["export_dna"])
|
||||
toolbar_layout.addWidget(QtWidgets.QLabel("|"))
|
||||
toolbar_layout.addWidget(toolbar_buttons["create_rl4"])
|
||||
toolbar_layout.addWidget(toolbar_buttons["delete_rl4"])
|
||||
toolbar_layout.addWidget(QtWidgets.QLabel("|"))
|
||||
toolbar_layout.addWidget(QtWidgets.QLabel("DNA文件:"))
|
||||
toolbar_layout.addWidget(dna_dropdown)
|
||||
toolbar_layout.addStretch()
|
||||
toolbar_layout.addWidget(status_label)
|
||||
|
||||
# 添加到主布局
|
||||
main_layout.addLayout(toolbar_layout)
|
||||
|
||||
#========================================== CONNECTIONS ==========================================
|
||||
def connections():
|
||||
"""
|
||||
连接工具栏UI信号和槽
|
||||
"""
|
||||
# 连接按钮点击事件到占位函数
|
||||
toolbar_buttons["load_preset"].clicked.connect(lambda: print("加载预设功能待实现"))
|
||||
toolbar_buttons["save_preset"].clicked.connect(lambda: print("保存预设功能待实现"))
|
||||
toolbar_buttons["import_dna"].clicked.connect(lambda: print("导入DNA功能待实现"))
|
||||
toolbar_buttons["export_dna"].clicked.connect(lambda: print("导出DNA功能待实现"))
|
||||
toolbar_buttons["create_rl4"].clicked.connect(lambda: print("创建RL4节点功能待实现"))
|
||||
toolbar_buttons["delete_rl4"].clicked.connect(lambda: print("删除RL4节点功能待实现"))
|
||||
|
||||
# 连接下拉菜单选择事件
|
||||
dna_dropdown.currentIndexChanged.connect(lambda index: print(f"选择的DNA文件索引: {index}"))
|
||||
|
||||
#===================================== PLACEHOLDER FUNCTION ===================================
|
||||
def toolbar_temp_function():
|
||||
return utils_toolbar.toolbar_temp_utils_function()
|
62
scripts/ui/ui_utils.py
Normal file
62
scripts/ui/ui_utils.py
Normal file
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
UI Utilities Module for Plugin
|
||||
UI工具模块 - 提供UI相关的通用函数
|
||||
"""
|
||||
|
||||
#===================================== IMPORT MODULES =====================================
|
||||
from Qt import QtWidgets, QtCore, QtGui
|
||||
from Qt.QtCompat import wrapInstance
|
||||
from maya import OpenMayaUI as omui
|
||||
import sys
|
||||
import os
|
||||
import config
|
||||
#===================================== UI UTILITY FUNCTIONS ===================================
|
||||
|
||||
TOOL_NAME = config.TOOL_NAME
|
||||
|
||||
def get_parent_widget(widget_name):
|
||||
"""
|
||||
根据控件名称查找父容器控件
|
||||
|
||||
Args:
|
||||
widget_name (str): 控件名称
|
||||
|
||||
Returns:
|
||||
QWidget: 找到的父容器控件,如果未找到则返回None
|
||||
"""
|
||||
# 查找主窗口中的所有控件
|
||||
main_window = None
|
||||
for widget in QtWidgets.QApplication.topLevelWidgets():
|
||||
if widget.objectName() == f"{TOOL_NAME}MainWindow" or widget.objectName().endswith("MainWindow"):
|
||||
main_window = widget
|
||||
break
|
||||
|
||||
if not main_window:
|
||||
print(f"无法找到主窗口,无法获取父容器: {widget_name}")
|
||||
return None
|
||||
|
||||
# 在主窗口中查找指定名称的控件
|
||||
found_widget = main_window.findChild(QtWidgets.QWidget, widget_name)
|
||||
if found_widget:
|
||||
return found_widget
|
||||
|
||||
# 如果未找到精确匹配,尝试模糊匹配
|
||||
for child in main_window.findChildren(QtWidgets.QWidget):
|
||||
if widget_name.lower() in child.objectName().lower():
|
||||
return child
|
||||
|
||||
print(f"无法找到控件: {widget_name}")
|
||||
return None
|
||||
|
||||
def get_maya_main_window():
|
||||
"""
|
||||
获取Maya主窗口
|
||||
|
||||
Returns:
|
||||
QWidget: Maya主窗口控件
|
||||
"""
|
||||
main_window_ptr = omui.MQtUtil.mainWindow()
|
||||
return wrapInstance(int(main_window_ptr), QtWidgets.QWidget)
|
Reference in New Issue
Block a user