MetaFusion/scripts/ui/widgets.py

231 lines
7.8 KiB
Python
Raw Permalink Normal View History

2025-02-06 04:46:41 +08:00
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#===================================== 1. Module Imports =====================================
2025-02-06 04:00:17 +08:00
import maya.cmds as cmds
2025-02-06 04:46:41 +08:00
import maya.mel as mel
import sys
import os
from scripts.config import data
2025-02-06 04:00:17 +08:00
try:
2025-02-06 04:46:41 +08:00
from PySide2 import QtCore, QtGui, QtWidgets
from shiboken2 import wrapInstance
except ImportError:
2025-02-06 04:00:17 +08:00
try:
2025-02-06 04:46:41 +08:00
from PySide6 import QtCore, QtGui, QtWidgets
from shiboken6 import wrapInstance
except ImportError:
2025-02-06 04:00:17 +08:00
try:
2025-02-06 04:46:41 +08:00
from PySide import QtCore, QtGui, QtWidgets
from shiboken import wrapInstance
2025-02-06 04:00:17 +08:00
except ImportError as e:
2025-02-06 04:46:41 +08:00
QtCore = QtGui = QtWidgets = None
wrapInstance = None
#===================================== 2. Base Widget Class =====================================
2025-02-06 04:00:17 +08:00
class BaseWidget(QtWidgets.QWidget):
"""基础控件类"""
def __init__(self, parent=None):
super(BaseWidget, self).__init__(parent)
2025-02-06 19:49:53 +08:00
self.SPACING = 4
self.MARGINS = 6
2025-02-06 04:00:17 +08:00
self.setup_ui()
def setup_ui(self):
pass
class IconButton(QtWidgets.QPushButton):
"""图标按钮"""
2025-02-06 19:49:53 +08:00
def __init__(self, icon_name, text, callback=None, parent=None):
super(IconButton, self).__init__(text, parent)
# 设置图标
2025-02-06 04:00:17 +08:00
if icon_name:
2025-02-06 04:46:41 +08:00
icon_path = os.path.join(data.ICONS_PATH, icon_name)
2025-02-06 04:00:17 +08:00
if os.path.exists(icon_path):
self.setIcon(QtGui.QIcon(icon_path))
2025-02-06 19:49:53 +08:00
# 连接回调
if callback:
self.clicked.connect(lambda checked=False, cb=callback: cb())
2025-02-06 04:00:17 +08:00
2025-02-06 19:49:53 +08:00
class LODGroup(QtWidgets.QGroupBox):
"""LOD分组控件"""
def __init__(self, lod_index, parent=None):
super(LODGroup, self).__init__(parent)
self.lod_index = lod_index
self.setTitle(f"LOD{lod_index}")
2025-02-06 04:00:17 +08:00
self.setup_ui()
def setup_ui(self):
layout = QtWidgets.QVBoxLayout(self)
2025-02-06 19:49:53 +08:00
layout.setSpacing(4)
layout.setContentsMargins(6, 6, 6, 6)
2025-02-06 04:00:17 +08:00
2025-02-06 19:49:53 +08:00
class SearchLineEdit(QtWidgets.QLineEdit):
"""搜索输入框"""
2025-02-06 04:00:17 +08:00
def __init__(self, parent=None):
2025-02-06 19:49:53 +08:00
super(SearchLineEdit, self).__init__(parent)
self.setPlaceholderText("搜索...")
self.setClearButtonEnabled(True)
2025-02-06 04:00:17 +08:00
2025-02-06 19:49:53 +08:00
class BlendShapeList(QtWidgets.QGroupBox):
"""BlendShape列表控件"""
def __init__(self, title, parent=None):
super(BlendShapeList, self).__init__(title, parent)
2025-02-06 04:00:17 +08:00
self.setup_ui()
def setup_ui(self):
layout = QtWidgets.QVBoxLayout(self)
self.list_widget = QtWidgets.QListWidget()
layout.addWidget(self.list_widget)
2025-02-06 19:49:53 +08:00
class BlendShapeControls(QtWidgets.QGroupBox):
"""BlendShape控制控件"""
2025-02-06 04:00:17 +08:00
def __init__(self, parent=None):
2025-02-06 19:49:53 +08:00
super(BlendShapeControls, self).__init__("控制", parent)
2025-02-06 04:00:17 +08:00
self.setup_ui()
def setup_ui(self):
layout = QtWidgets.QVBoxLayout(self)
2025-02-06 19:49:53 +08:00
self.value_slider = QtWidgets.QSlider(QtCore.Qt.Horizontal)
layout.addWidget(self.value_slider)
2025-02-06 04:00:17 +08:00
2025-02-06 19:49:53 +08:00
class DNABrowser(QtWidgets.QGroupBox):
"""DNA浏览器控件"""
dnaSelected = QtCore.Signal(str)
2025-02-06 04:00:17 +08:00
def __init__(self, parent=None):
2025-02-06 19:49:53 +08:00
super(DNABrowser, self).__init__("DNA浏览器", parent)
2025-02-06 04:00:17 +08:00
self.setup_ui()
def setup_ui(self):
layout = QtWidgets.QVBoxLayout(self)
2025-02-06 19:49:53 +08:00
self.list_widget = QtWidgets.QListWidget()
layout.addWidget(self.list_widget)
def selectedItems(self):
"""获取选中项"""
return self.list_widget.selectedItems()
2025-02-06 04:00:17 +08:00
2025-02-06 19:49:53 +08:00
def itemSelectionChanged(self):
"""选择变化信号"""
return self.list_widget.itemSelectionChanged()
2025-02-06 04:00:17 +08:00
2025-02-06 19:49:53 +08:00
def connect(self, callback):
"""连接选择变化信号"""
self.list_widget.itemSelectionChanged.connect(callback)
2025-02-06 04:00:17 +08:00
2025-02-06 19:49:53 +08:00
class DescriptionWidget(QtWidgets.QGroupBox):
"""描述控件"""
2025-02-06 04:00:17 +08:00
def __init__(self, parent=None):
2025-02-06 19:49:53 +08:00
super(DescriptionWidget, self).__init__("描述", parent)
2025-02-06 04:00:17 +08:00
self.setup_ui()
def setup_ui(self):
layout = QtWidgets.QVBoxLayout(self)
2025-02-06 19:49:53 +08:00
self.text_edit = QtWidgets.QTextEdit()
self.text_edit.setReadOnly(True)
layout.addWidget(self.text_edit)
2025-02-06 04:00:17 +08:00
2025-02-06 19:49:53 +08:00
class SliderWithValue(QtWidgets.QWidget):
"""带数值显示的滑块"""
valueChanged = QtCore.Signal(float)
def __init__(self, min_val=0.0, max_val=1.0, default=0.0, parent=None):
super(SliderWithValue, self).__init__(parent)
self.setup_ui(min_val, max_val, default)
2025-02-06 04:00:17 +08:00
2025-02-06 19:49:53 +08:00
def setup_ui(self, min_val, max_val, default):
layout = QtWidgets.QHBoxLayout(self)
2025-02-06 04:00:17 +08:00
layout.setContentsMargins(0, 0, 0, 0)
2025-02-06 19:49:53 +08:00
self.slider = QtWidgets.QSlider(QtCore.Qt.Horizontal)
self.slider.setRange(int(min_val * 100), int(max_val * 100))
self.slider.setValue(int(default * 100))
2025-02-06 04:00:17 +08:00
2025-02-06 19:49:53 +08:00
self.value_label = QtWidgets.QLabel(f"{default:.2f}")
self.value_label.setMinimumWidth(40)
2025-02-06 04:00:17 +08:00
2025-02-06 19:49:53 +08:00
layout.addWidget(self.slider)
layout.addWidget(self.value_label)
2025-02-06 04:00:17 +08:00
2025-02-06 19:49:53 +08:00
self.slider.valueChanged.connect(self._on_slider_changed)
2025-02-06 04:00:17 +08:00
2025-02-06 19:49:53 +08:00
def _on_slider_changed(self, value):
float_value = value / 100.0
self.value_label.setText(f"{float_value:.2f}")
self.valueChanged.emit(float_value)
2025-02-06 04:00:17 +08:00
2025-02-06 19:49:53 +08:00
class ModernTabWidget(QtWidgets.QTabWidget):
"""现代风格标签页控件"""
def __init__(self, parent=None):
super(ModernTabWidget, self).__init__(parent)
self.setTabBar(TabBar())
self.setDocumentMode(True)
self.setMovable(True)
2025-02-06 04:00:17 +08:00
2025-02-06 19:49:53 +08:00
class TabBar(QtWidgets.QTabBar):
"""自定义标签栏"""
def __init__(self, parent=None):
super(TabBar, self).__init__(parent)
self.setDrawBase(False)
self.setExpanding(False)
2025-02-06 04:00:17 +08:00
2025-02-06 19:49:53 +08:00
class ModernToolBar(QtWidgets.QToolBar):
"""现代风格工具栏"""
def __init__(self, parent=None):
super(ModernToolBar, self).__init__(parent)
self.setMovable(False)
self.setFloatable(False)
self.setIconSize(QtCore.QSize(16, 16))
def addAction(self, icon, text, callback):
"""添加工具栏按钮"""
action = QtWidgets.QAction(text, self)
if icon:
icon_path = os.path.join(data.ICONS_PATH, icon)
if os.path.exists(icon_path):
action.setIcon(QtGui.QIcon(icon_path))
action.triggered.connect(callback)
super(ModernToolBar, self).addAction(action)
return action
def addStretch(self):
"""添加弹性空间"""
spacer = QtWidgets.QWidget()
spacer.setSizePolicy(QtWidgets.QSizePolicy.Expanding,
QtWidgets.QSizePolicy.Preferred)
self.addWidget(spacer)
class GradientGroupBox(QtWidgets.QGroupBox):
"""渐变背景分组框"""
def __init__(self, title, parent=None):
super(GradientGroupBox, self).__init__(title, parent)
class ModernComboBox(QtWidgets.QComboBox):
"""现代风格下拉框"""
def __init__(self, parent=None):
super(ModernComboBox, self).__init__(parent)
class ModernLabel(QtWidgets.QLabel):
"""现代风格标签"""
def __init__(self, text, parent=None):
super(ModernLabel, self).__init__(text, parent)
class ModernLineEdit(QtWidgets.QLineEdit):
"""现代风格输入框"""
def __init__(self, read_only=False, parent=None):
super(ModernLineEdit, self).__init__(parent)
self.setReadOnly(read_only)
class ModernToolButton(QtWidgets.QToolButton):
"""现代风格工具按钮"""
def __init__(self, icon, text, parent=None):
super(ModernToolButton, self).__init__(parent)
self.setText(text)
if icon:
icon_path = os.path.join(data.ICONS_PATH, icon)
if os.path.exists(icon_path):
self.setIcon(QtGui.QIcon(icon_path))
self.setIconSize(QtCore.QSize(16, 16))