MetaFusion/scripts/DNA_Browser.py
2025-01-11 16:53:48 +08:00

238 lines
7.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from PySide2 import QtWidgets, QtCore, QtGui
import maya.cmds as cmds
import os
class DNABrowserWidget(QtWidgets.QWidget):
dna_selected = QtCore.Signal(str) # 信号当DNA被选中时发出
def __init__(self, dna_path, img_path, parent=None):
super().__init__(parent)
self.dna_path = dna_path
self.img_path = img_path
self.setup_ui()
self.scan_dna_files()
self.update_grid()
def setup_ui(self):
# 创建主布局
self.main_layout = QtWidgets.QVBoxLayout(self)
self.main_layout.setContentsMargins(0, 0, 0, 0)
# 创建流式布局容器
self.flow_widget = QtWidgets.QWidget()
self.flow_layout = FlowLayout(self.flow_widget)
self.flow_layout.setSpacing(5)
# 创建滚动区域
self.scroll_area = QtWidgets.QScrollArea()
self.scroll_area.setWidgetResizable(True)
self.scroll_area.setWidget(self.flow_widget)
self.scroll_area.setStyleSheet("""
QScrollArea {
border: none;
background-color: transparent;
}
QScrollBar:vertical {
border: none;
background: #F0F0F0;
width: 8px;
margin: 0px;
}
QScrollBar::handle:vertical {
background: #CCCCCC;
border-radius: 4px;
min-height: 20px;
}
QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical {
height: 0px;
}
""")
self.main_layout.addWidget(self.scroll_area)
def scan_dna_files(self):
"""扫描DNA文件夹并建立索引"""
self.dna_files = {}
if not os.path.exists(self.dna_path):
cmds.warning(f"DNA path not found: {self.dna_path}")
return
if not os.path.exists(self.img_path):
cmds.warning(f"Image path not found: {self.img_path}")
return
for file in os.listdir(self.dna_path):
if file.endswith('.dna'):
name = os.path.splitext(file)[0]
dna_file = os.path.join(self.dna_path, file).replace("\\", "/")
# 直接在img目录下查找图片
img_file = None
for ext in ['.jpg', '.png', '.jpeg']:
img_path = os.path.join(self.img_path, f"{name}{ext}").replace("\\", "/")
if os.path.exists(img_path):
img_file = img_path
break
self.dna_files[name] = {
'dna_path': dna_file,
'img_path': img_file
}
# 打印调试信息
print(f"DNA file: {name}")
print(f" DNA path: {dna_file}")
print(f" Image path: {img_file}")
print(f" Image exists: {bool(img_file and os.path.exists(img_file))}")
def update_grid(self):
"""更新DNA网格"""
# 清除现有按钮
for i in reversed(range(self.flow_layout.count())):
self.flow_layout.itemAt(i).widget().deleteLater()
# 计算按钮大小 - 减小到原来的1/4左右
container_width = self.flow_widget.width() or 300
button_width = (container_width - 60) // 6 # 每行6个按钮
button_height = int(button_width * 1.2) # 保持宽高比
# 创建DNA样本按钮
for name, info in self.dna_files.items():
dna_btn = self.create_dna_button(name, info, button_width, button_height)
self.flow_layout.addWidget(dna_btn)
def create_dna_button(self, name, info, width, height):
"""创建DNA按钮"""
btn = QtWidgets.QPushButton()
btn.setFixedSize(width, height)
# 创建按钮布局
layout = QtWidgets.QVBoxLayout(btn)
layout.setContentsMargins(2, 2, 2, 2)
layout.setSpacing(1)
# 创建图标标签
icon_label = QtWidgets.QLabel()
icon_label.setAlignment(QtCore.Qt.AlignCenter)
if info['img_path']:
pixmap = QtGui.QPixmap(info['img_path'])
scaled_pixmap = pixmap.scaled(
width - 4,
height - 16,
QtCore.Qt.KeepAspectRatio,
QtCore.Qt.SmoothTransformation
)
icon_label.setPixmap(scaled_pixmap)
else:
icon_label.setText("No Image")
icon_label.setStyleSheet("color: #FFFFFF; font-size: 8px;") # 改为白色
# 创建文本标签
text_label = QtWidgets.QLabel(name)
text_label.setAlignment(QtCore.Qt.AlignCenter)
text_label.setStyleSheet("color: #FFFFFF; font-size: 8px;") # 改为白色
layout.addWidget(icon_label)
layout.addWidget(text_label)
# 设置样式 - 保持黑色背景,文字改为白色
btn.setStyleSheet("""
QPushButton {
background-color: #303030;
border: 1px solid #202020;
border-radius: 5px;
padding: 2px;
color: #FFFFFF; /* 按钮文字颜色改为白色 */
}
QPushButton:hover {
background-color: #404040;
border: 1px solid #303030;
}
QPushButton:pressed {
background-color: #202020;
}
""")
btn.setProperty('dna_path', info['dna_path'])
btn.clicked.connect(lambda: self.on_dna_selected(info['dna_path']))
return btn
def on_dna_selected(self, dna_path):
"""当DNA被选中时发出信号"""
self.dna_selected.emit(dna_path)
class FlowLayout(QtWidgets.QLayout):
def __init__(self, parent=None):
super().__init__(parent)
self.itemList = []
self.spacing_x = 5
self.spacing_y = 5
def addItem(self, item):
self.itemList.append(item)
def count(self):
return len(self.itemList)
def itemAt(self, index):
if 0 <= index < len(self.itemList):
return self.itemList[index]
return None
def takeAt(self, index):
if 0 <= index < len(self.itemList):
return self.itemList.pop(index)
return None
def expandingDirections(self):
return QtCore.Qt.Orientations(QtCore.Qt.Orientation(0))
def hasHeightForWidth(self):
return True
def heightForWidth(self, width):
height = self.doLayout(QtCore.QRect(0, 0, width, 0), True)
return height
def setGeometry(self, rect):
super().setGeometry(rect)
self.doLayout(rect, False)
def sizeHint(self):
return self.minimumSize()
def minimumSize(self):
size = QtCore.QSize()
for item in self.itemList:
size = size.expandedTo(item.minimumSize())
return size
def doLayout(self, rect, testOnly):
x = rect.x()
y = rect.y()
lineHeight = 0
for item in self.itemList:
widget = item.widget()
spaceX = self.spacing_x
spaceY = self.spacing_y
nextX = x + item.sizeHint().width() + spaceX
if nextX - spaceX > rect.right() and lineHeight > 0:
x = rect.x()
y = y + lineHeight + spaceY
nextX = x + item.sizeHint().width() + spaceX
lineHeight = 0
if not testOnly:
item.setGeometry(QtCore.QRect(QtCore.QPoint(x, y), item.sizeHint()))
x = nextX
lineHeight = max(lineHeight, item.sizeHint().height())
return y + lineHeight - rect.y()
def create_browser(dna_path, img_path, parent=None):
"""创建并返回DNA浏览器实例"""
return DNABrowserWidget(dna_path, img_path, parent)