238 lines
7.9 KiB
Python
238 lines
7.9 KiB
Python
#!/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)
|