This commit is contained in:
2025-05-12 02:07:24 +08:00
parent 5e5aa4f670
commit ba01b8fc6d
2 changed files with 220 additions and 92 deletions

View File

@@ -55,6 +55,9 @@ selected_controller = None
original_joint_properties = {}
original_controller_properties = {}
# DNA预览按钮默认尺寸
DEFAULT_DNA_BUTTON_SIZE = (90, 120) # 保持3:4的宽高比例
#========================================== FUNCTIONS ========================================
#------------------------------------ DNA PREVIEW ------------------------------------
@@ -251,87 +254,119 @@ def create_dna_preview_button(dna_info, item_size, on_click_callback):
QPushButton: 创建的DNA预览按钮
"""
try:
# 创建按钮
button = QtWidgets.QPushButton()
button.setObjectName(f"dna_button_{dna_info['name']}")
button.setFixedSize(item_size[0], item_size[1])
button.setProperty("class", "dna-preview-button")
button.setCursor(QtCore.Qt.PointingHandCursor) # 鼠标悬停时显示手型光标
# 调试信息
print(f"创建DNA按钮: {dna_info['name']}, 路径: {dna_info['image_path']}, 尺寸: {item_size}")
# 创建带有图标和文字的垂直布局按钮
dna_button = QtWidgets.QWidget()
dna_button.setFixedSize(item_size[0], item_size[1])
dna_button.setObjectName(f"dna_button_{dna_info['name']}")
dna_button.setCursor(QtCore.Qt.PointingHandCursor)
# 创建垂直布局
layout = QtWidgets.QVBoxLayout(button)
layout.setContentsMargins(0, 0, 0, 0)
layout.setSpacing(2)
# 创建图像容器
image_container = QtWidgets.QWidget()
image_container.setObjectName(f"image_container_{dna_info['name']}")
image_container.setFixedSize(item_size[0], item_size[0] - 10) # 留出底部名称空间
image_container.setStyleSheet("background-color: #2A2A2A; border-radius: 4px;")
layout = QtWidgets.QVBoxLayout(dna_button)
layout.setContentsMargins(2, 2, 2, 2)
layout.setSpacing(1) # 更小的间距
# 创建图像标签
image_label = QtWidgets.QLabel(image_container)
image_label.setObjectName(f"image_{dna_info['name']}")
image_label.setAlignment(QtCore.Qt.AlignCenter)
img_label = QtWidgets.QLabel()
img_label.setAlignment(QtCore.Qt.AlignCenter)
# 使用预缓存加载图像
pixmap = get_pixmap(dna_info['image_path'], item_size[0] - 16, item_size[0] - 26)
image_label.setPixmap(pixmap)
# 加载并缩放图像
img_height = int(item_size[1] * 0.8) # 图像占80%高度
img_width = item_size[0] - 4 # 减去边距
# 创建图像标签布局
image_layout = QtWidgets.QVBoxLayout(image_container)
image_layout.setContentsMargins(8, 8, 8, 8)
image_layout.addWidget(image_label, 0, QtCore.Qt.AlignCenter)
pixmap = QtGui.QPixmap(dna_info['image_path'])
if pixmap.isNull():
print(f"错误: 无法加载图像 {dna_info['image_path']}")
# 创建一个默认的纯色图片
pixmap = QtGui.QPixmap(img_width, img_height)
pixmap.fill(QtGui.QColor(60, 60, 60))
else:
# 缩放图像以适应,但保持纵横比
pixmap = pixmap.scaled(
img_width,
img_height,
QtCore.Qt.KeepAspectRatio,
QtCore.Qt.SmoothTransformation
)
# 创建名称标签
name_label = QtWidgets.QLabel(dna_info['name'])
name_label.setObjectName(f"name_{dna_info['name']}")
name_label.setAlignment(QtCore.Qt.AlignCenter)
name_label.setStyleSheet("""
background-color: transparent;
color: #E0E0E0;
# 设置图像标签的图像
img_label.setPixmap(pixmap)
img_label.setFixedHeight(img_height)
# 创建文本标签
text_label = QtWidgets.QLabel(dna_info['name'])
text_label.setAlignment(QtCore.Qt.AlignCenter)
text_label.setStyleSheet("""
color: white;
font-size: 9px; /* 更小的字体 */
font-weight: bold;
padding: 4px;
margin-top: 0px;
padding-top: 0px;
""")
text_label.setWordWrap(True) # 允许文本换行
text_label.setFixedHeight(15) # 固定文本高度
# 添加控件到布局
layout.addWidget(img_label)
layout.addWidget(text_label)
# 设置整体样式
dna_button.setStyleSheet("""
background-color: #333333;
border: 1px solid #444444;
border-radius: 3px;
""")
# 添加到布局
layout.addWidget(image_container, 0, QtCore.Qt.AlignCenter)
layout.addWidget(name_label, 0, QtCore.Qt.AlignCenter)
# 设置按钮样式
button.setStyleSheet("""
QPushButton {
background-color: #333333;
# 创建透明按钮覆盖整个区域以处理点击
overlay_button = QtWidgets.QPushButton(dna_button)
overlay_button.setObjectName("overlayButton")
overlay_button.setStyleSheet("""
#overlayButton {
background-color: transparent;
border: none;
border-radius: 6px;
padding: 0px;
}
QPushButton:hover {
background-color: #444444;
#overlayButton:hover {
background-color: rgba(0, 122, 204, 0.2);
}
QPushButton:pressed {
background-color: #555555;
#overlayButton:pressed {
background-color: rgba(0, 122, 204, 0.3);
}
""")
overlay_button.resize(dna_button.size())
overlay_button.clicked.connect(lambda: on_click_callback(dna_info['dna_path']))
# 设置按钮数据
button.setProperty("dna_path", dna_info['dna_path'])
# 存储DNA路径属性
dna_button.setProperty("dna_path", dna_info['dna_path'])
# 连接点击信号
button.clicked.connect(lambda: on_click_callback(dna_info['dna_path']))
return button
return dna_button
except Exception as e:
print(f"创建DNA预览按钮失败 ({dna_info.get('name', 'unknown')}): {str(e)}")
import traceback
traceback.print_exc()
# 返回一个简单的替代按钮
fallback_button = QtWidgets.QPushButton(dna_info.get('name', 'DNA'))
fallback_button.setFixedSize(item_size[0], item_size[1])
fallback_widget = QtWidgets.QWidget()
fallback_widget.setFixedSize(item_size[0], item_size[1])
fallback_layout = QtWidgets.QVBoxLayout(fallback_widget)
fallback_layout.setContentsMargins(2, 2, 2, 2)
fallback_label = QtWidgets.QLabel(dna_info.get('name', 'DNA'))
fallback_label.setAlignment(QtCore.Qt.AlignCenter)
fallback_label.setStyleSheet("color: white; font-weight: bold;")
fallback_layout.addWidget(fallback_label)
# 添加点击功能
if on_click_callback:
fallback_button = QtWidgets.QPushButton(fallback_widget)
fallback_button.setStyleSheet("background: transparent; border: none;")
fallback_button.resize(fallback_widget.size())
fallback_button.clicked.connect(lambda: on_click_callback(dna_info.get('dna_path', '')))
return fallback_button
return fallback_widget
# 缓存上一次的布局信息,避免不必要的重新计算
_last_layout_info = {
@@ -353,6 +388,11 @@ def load_dna_preview_buttons(ui_instance):
if not ui_instance or not hasattr(ui_instance, 'controls'):
print("无效的UI实例无法加载DNA预览按钮")
return False
# 检查是否有dna_button_size属性没有则初始化
if not hasattr(ui_instance, 'dna_button_size'):
ui_instance.dna_button_size = DEFAULT_DNA_BUTTON_SIZE
print(f"警告: UI实例没有dna_button_size属性使用默认值{DEFAULT_DNA_BUTTON_SIZE}")
# 获取DNA文件列表
dna_files = ui_instance.dna_files
@@ -751,37 +791,62 @@ def on_presets_slider_changed(ui_instance, value):
print("警告: UI实例无效无法调整预览按钮大小")
return
# 计算新的按钮尺寸 (基于滑块值进行缩放)
# 范围从最小100x120到最大180x220
base_width = 140 # 基础宽度
base_height = 170 # 基础高度
# 检查是否有dna_button_size属性没有则初始化
if not hasattr(ui_instance, 'dna_button_size'):
ui_instance.dna_button_size = DEFAULT_DNA_BUTTON_SIZE
print(f"警告: UI实例没有dna_button_size属性使用默认值{DEFAULT_DNA_BUTTON_SIZE}")
# 调试尺寸信息
print(f"当前按钮基础尺寸: {DEFAULT_DNA_BUTTON_SIZE[0]}x{DEFAULT_DNA_BUTTON_SIZE[1]}")
# 获取滑块范围
min_val = ui_instance.controls["presets_slider"].minimum()
max_val = ui_instance.controls["presets_slider"].maximum()
mid_val = (min_val + max_val) / 2
# 避免除以零
scale_range = max(1, max_val - min_val)
# 确保滑块值在范围内
value = max(min_val, min(max_val, value))
# 计算缩放比例 (0.7 到 1.3)
scale_factor = 0.7 + 0.6 * ((value - min_val) / scale_range)
# 计算缩放比例 - 更平滑的缩放效果
# 以100为中心点低于100缩小高于100放大
if value <= mid_val:
# 从0.8到1.0
scale_factor = 0.8 + 0.2 * ((value - min_val) / (mid_val - min_val))
else:
# 从1.0到1.2
scale_factor = 1.0 + 0.2 * ((value - mid_val) / (max_val - mid_val))
# 应用缩放
new_width = int(base_width * scale_factor)
new_height = int(base_height * scale_factor)
# 确保在合理范围内
scale_factor = max(0.7, min(1.3, scale_factor))
# 确保尺寸在合理范围内
new_width = max(100, min(180, new_width))
new_height = max(120, min(220, new_height))
# 从基础尺寸计算缩放后的尺寸,保持宽高比
new_width = int(DEFAULT_DNA_BUTTON_SIZE[0] * scale_factor)
new_height = int(DEFAULT_DNA_BUTTON_SIZE[1] * scale_factor)
# 确保尺寸不会太小或太大
new_width = max(60, min(130, new_width))
new_height = max(80, min(170, new_height))
# 确保宽高比例正确 - 约为3:4
aspect_ratio = DEFAULT_DNA_BUTTON_SIZE[0] / DEFAULT_DNA_BUTTON_SIZE[1]
# 优先以高度为准,调整宽度
new_width = int(new_height * aspect_ratio)
# 确保宽高为偶数
if new_width % 2 != 0:
new_width += 1
if new_height % 2 != 0:
new_height += 1
# 输出调试信息
print(f"调整DNA按钮大小: {new_width}x{new_height}, 缩放因子: {scale_factor:.2f}")
# 更新按钮尺寸
old_size = ui_instance.dna_button_size
ui_instance.dna_button_size = (new_width, new_height)
# 如果尺寸有明显变化,重新加载DNA预览按钮
if abs(old_size[0] - new_width) > 10 or abs(old_size[1] - new_height) > 10:
# 重新加载预览按钮
load_dna_preview_buttons(ui_instance)
# 重新加载预览按钮
load_dna_preview_buttons(ui_instance)
except Exception as e:
import traceback