Update
This commit is contained in:
@@ -73,6 +73,10 @@ class RiggingUI(ui_utils.BaseUI):
|
||||
self.main_widget = QtWidgets.QWidget()
|
||||
self.main_widget.setObjectName("riggingMainWidget")
|
||||
|
||||
# 初始化DNA文件列表和按钮尺寸
|
||||
self.dna_files = []
|
||||
self.dna_button_size = (120, 150)
|
||||
|
||||
# 初始化UI
|
||||
self.create_widgets()
|
||||
self.create_layouts()
|
||||
@@ -81,6 +85,29 @@ class RiggingUI(ui_utils.BaseUI):
|
||||
# 更新UI文本
|
||||
self.update_language()
|
||||
|
||||
# 加载DNA文件和预览图 - 移到最后执行确保所有控件已创建
|
||||
self.load_dna_files()
|
||||
|
||||
def closeEvent(self, event):
|
||||
"""
|
||||
窗口关闭事件处理
|
||||
清理缓存和资源
|
||||
"""
|
||||
try:
|
||||
# 清理图片缓存
|
||||
from scripts.utils import utils_rigging
|
||||
utils_rigging.clear_pixmap_cache()
|
||||
|
||||
# 调用父类的关闭事件
|
||||
super().closeEvent(event)
|
||||
except Exception as e:
|
||||
print(f"窗口关闭处理失败: {str(e)}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
# 确保窗口正常关闭
|
||||
event.accept()
|
||||
|
||||
#========================================= WIDGET =======================================
|
||||
def create_widgets(self):
|
||||
"""
|
||||
@@ -121,47 +148,6 @@ class RiggingUI(ui_utils.BaseUI):
|
||||
self.controls["presets_flow_layout"].setContentsMargins(5, 5, 5, 5)
|
||||
self.controls["presets_flow_layout"].setSpacing(10)
|
||||
|
||||
# 添加测试预设项
|
||||
for i in range(6): # 添加6个预设项,如图中所示
|
||||
col = i % 6
|
||||
row = i // 6
|
||||
|
||||
preset_widget = QtWidgets.QWidget()
|
||||
preset_widget.setObjectName(f"preset_{i}")
|
||||
preset_widget.setMinimumSize(120, 150) # 设置预设项大小
|
||||
preset_widget.setMaximumSize(120, 150)
|
||||
|
||||
# 预设布局
|
||||
preset_layout = QtWidgets.QVBoxLayout(preset_widget)
|
||||
preset_layout.setContentsMargins(0, 0, 0, 0)
|
||||
preset_layout.setSpacing(2)
|
||||
|
||||
# 预设图片
|
||||
preset_image = QtWidgets.QLabel()
|
||||
preset_image.setObjectName(f"preset_image_{i}")
|
||||
preset_image.setMinimumSize(120, 120)
|
||||
preset_image.setMaximumSize(120, 120)
|
||||
preset_image.setScaledContents(True)
|
||||
preset_image.setStyleSheet("background-color: #333333; border: 1px solid #555555;")
|
||||
|
||||
# 加载测试图片
|
||||
pixmap = QtGui.QPixmap(os.path.join(ASSETS_PATH, "metahuman_placeholder.png"))
|
||||
if not pixmap.isNull():
|
||||
preset_image.setPixmap(pixmap)
|
||||
|
||||
# 预设标签
|
||||
preset_label = QtWidgets.QLabel("METAHUMAN")
|
||||
preset_label.setObjectName(f"preset_label_{i}")
|
||||
preset_label.setAlignment(QtCore.Qt.AlignCenter)
|
||||
preset_label.setStyleSheet("color: white; background-color: rgba(0, 0, 0, 128);")
|
||||
|
||||
# 添加到布局
|
||||
preset_layout.addWidget(preset_image)
|
||||
preset_layout.addWidget(preset_label)
|
||||
|
||||
# 添加到流布局
|
||||
self.controls["presets_flow_layout"].addWidget(preset_widget, row, col)
|
||||
|
||||
# 设置滚动区域内容
|
||||
self.controls["presets_scroll_area"].setWidget(self.controls["presets_content"])
|
||||
|
||||
@@ -171,7 +157,7 @@ class RiggingUI(ui_utils.BaseUI):
|
||||
self.controls["presets_slider_layout"].setSpacing(5)
|
||||
|
||||
# 数量显示
|
||||
self.controls["presets_count_label"] = QtWidgets.QLabel("99")
|
||||
self.controls["presets_count_label"] = QtWidgets.QLabel("0")
|
||||
self.controls["presets_count_label"].setObjectName("presetsCountLabel")
|
||||
self.controls["presets_count_label"].setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.controls["presets_count_label"].setStyleSheet("font-weight: bold;")
|
||||
@@ -486,14 +472,15 @@ class RiggingUI(ui_utils.BaseUI):
|
||||
# 设置分割器的伸缩因子
|
||||
for i in range(self.splitters["main_splitter"].count()):
|
||||
self.splitters["main_splitter"].setStretchFactor(i, 1)
|
||||
|
||||
|
||||
# 监听预设内容区域大小变化,更新DNA网格布局
|
||||
self.controls["presets_content"].resizeEvent = lambda event: utils_rigging.on_presets_content_resize(event, self)
|
||||
|
||||
#======================================= FUNCTIONS ======================================
|
||||
def create_connections(self):
|
||||
"""
|
||||
创建信号连接,设置UI控件的交互行为
|
||||
"""
|
||||
# 导入绑定工具函数
|
||||
from scripts.utils import utils_rigging
|
||||
|
||||
# 预设导入和导出按钮
|
||||
self.buttons["export_presets"].clicked.connect(utils_rigging.export_dna)
|
||||
@@ -506,4 +493,25 @@ class RiggingUI(ui_utils.BaseUI):
|
||||
# 底部按钮连接
|
||||
self.buttons["remove_all"].clicked.connect(utils_rigging.remove_all)
|
||||
self.buttons["import_skeleton"].clicked.connect(utils_rigging.import_skeleton)
|
||||
self.buttons["build_rigging"].clicked.connect(utils_rigging.build_rigging)
|
||||
self.buttons["build_rigging"].clicked.connect(utils_rigging.build_rigging)
|
||||
|
||||
def load_dna_files(self):
|
||||
"""
|
||||
加载DNA文件和预览
|
||||
在所有UI控件创建完成后执行
|
||||
"""
|
||||
try:
|
||||
# 从utils_rigging加载DNA文件和预览图
|
||||
from scripts.utils import utils_rigging
|
||||
self.dna_files = utils_rigging.get_dna_files()
|
||||
|
||||
# 更新预设数量标签
|
||||
if 'presets_count_label' in self.controls:
|
||||
self.controls['presets_count_label'].setText(str(len(self.dna_files)))
|
||||
|
||||
# 调用utils_rigging中的加载预览按钮函数
|
||||
utils_rigging.load_dna_preview_buttons(self)
|
||||
except Exception as e:
|
||||
import traceback
|
||||
print(f"加载DNA文件失败: {str(e)}")
|
||||
traceback.print_exc()
|
@@ -20,6 +20,34 @@ QLabel#mainTitleLabel {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
/* ==================== DNA预览按钮样式 ==================== */
|
||||
QPushButton.dna-preview-button {
|
||||
background-color: #2D2D30;
|
||||
border: 1px solid #3E3E42;
|
||||
border-radius: 8px;
|
||||
padding: 0;
|
||||
margin: 4px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
QPushButton.dna-preview-button:hover {
|
||||
border: 1px solid #007ACC;
|
||||
background-color: #3E3E42;
|
||||
}
|
||||
|
||||
QPushButton.dna-preview-button:pressed {
|
||||
border: 1px solid #0062A3;
|
||||
background-color: #1E1E1E;
|
||||
}
|
||||
|
||||
QPushButton.dna-preview-button QLabel {
|
||||
color: #FFFFFF;
|
||||
font-size: 11px;
|
||||
border-radius: 0;
|
||||
border-bottom-left-radius: 7px;
|
||||
border-bottom-right-radius: 7px;
|
||||
}
|
||||
|
||||
/* ==================== 标签页样式 ==================== */
|
||||
QTabWidget::pane {
|
||||
border: 1px solid #1E1E1E;
|
||||
|
@@ -57,6 +57,477 @@ original_controller_properties = {}
|
||||
|
||||
#========================================== FUNCTIONS ========================================
|
||||
|
||||
#------------------------------------ DNA PREVIEW ------------------------------------
|
||||
def get_dna_files():
|
||||
"""
|
||||
获取所有DNA文件及其对应的预览图
|
||||
|
||||
Returns:
|
||||
list: 包含DNA文件信息的字典列表,每个字典包含:
|
||||
- name: DNA文件名(不含扩展名)
|
||||
- dna_path: DNA文件的完整路径
|
||||
- image_path: 预览图的完整路径
|
||||
"""
|
||||
dna_files = []
|
||||
default_preview = os.path.join(DNA_IMG_PATH, "Preview.png")
|
||||
|
||||
# 调试信息
|
||||
print(f"加载DNA文件目录: {DNA_FILE_PATH}")
|
||||
print(f"加载DNA图片目录: {DNA_IMG_PATH}")
|
||||
|
||||
# 确保目录存在
|
||||
if not os.path.exists(DNA_FILE_PATH):
|
||||
print(f"错误: DNA文件目录不存在: {DNA_FILE_PATH}")
|
||||
return dna_files
|
||||
|
||||
if not os.path.exists(DNA_IMG_PATH):
|
||||
print(f"错误: DNA图片目录不存在: {DNA_IMG_PATH}")
|
||||
|
||||
if not os.path.exists(default_preview):
|
||||
print(f"错误: 默认预览图不存在: {default_preview}")
|
||||
|
||||
# 列出所有DNA文件
|
||||
try:
|
||||
dna_file_list = os.listdir(DNA_FILE_PATH)
|
||||
print(f"找到 {len(dna_file_list)} 个文件在 DNA目录")
|
||||
except Exception as e:
|
||||
print(f"列出DNA文件失败: {str(e)}")
|
||||
return dna_files
|
||||
|
||||
# 获取所有可用的预览图文件名(不带扩展名),只查询一次目录提高性能
|
||||
available_images = set()
|
||||
try:
|
||||
img_files = os.listdir(DNA_IMG_PATH)
|
||||
for img_file in img_files:
|
||||
if img_file.lower().endswith('.png'):
|
||||
base_name = os.path.splitext(img_file)[0]
|
||||
available_images.add(base_name)
|
||||
except Exception as e:
|
||||
print(f"列出图片文件失败: {str(e)}")
|
||||
|
||||
# 处理每个DNA文件
|
||||
for file_name in dna_file_list:
|
||||
if file_name.lower().endswith('.dna'):
|
||||
# 获取不含扩展名的文件名
|
||||
name = os.path.splitext(file_name)[0]
|
||||
dna_path = os.path.join(DNA_FILE_PATH, file_name).replace("\\", "/")
|
||||
|
||||
# 检查预览图是否存在,不重复检查文件系统提高性能
|
||||
if name in available_images:
|
||||
image_path = os.path.join(DNA_IMG_PATH, f"{name}.png").replace("\\", "/")
|
||||
else:
|
||||
image_path = default_preview
|
||||
print(f"未找到预览图: {name}.png, 使用默认预览图")
|
||||
|
||||
dna_files.append({
|
||||
"name": name,
|
||||
"dna_path": dna_path,
|
||||
"image_path": image_path
|
||||
})
|
||||
|
||||
print(f"成功加载 {len(dna_files)} 个DNA文件")
|
||||
return dna_files
|
||||
|
||||
def load_selected_dna(dna_path, ui_instance=None):
|
||||
"""
|
||||
加载用户选择的DNA文件
|
||||
|
||||
Args:
|
||||
dna_path (str): DNA文件路径
|
||||
ui_instance: UI实例,用于更新UI状态
|
||||
|
||||
Returns:
|
||||
bool: 是否成功加载
|
||||
"""
|
||||
try:
|
||||
if not os.path.exists(dna_path):
|
||||
print(f"DNA文件不存在: {dna_path}")
|
||||
return False
|
||||
|
||||
print(f"加载DNA文件: {dna_path}")
|
||||
|
||||
# 更新UI中的DNA路径输入框(如果有UI实例)
|
||||
if ui_instance and hasattr(ui_instance, 'controls') and 'presets_dna_input' in ui_instance.controls:
|
||||
ui_instance.controls['presets_dna_input'].setText(dna_path)
|
||||
|
||||
# 这里可以添加实际的DNA文件加载逻辑
|
||||
# 例如通过MetaHuman DNA Calibration库读取DNA文件
|
||||
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"加载DNA文件失败: {str(e)}")
|
||||
return False
|
||||
|
||||
def calculate_grid_layout(parent_width, item_width, spacing):
|
||||
"""
|
||||
根据父容器宽度计算每行可以容纳的项目数量
|
||||
|
||||
Args:
|
||||
parent_width (int): 父容器宽度
|
||||
item_width (int): 每个项目的宽度
|
||||
spacing (int): 项目间的间距
|
||||
|
||||
Returns:
|
||||
int: 每行可容纳的项目数量
|
||||
"""
|
||||
if parent_width <= 0 or item_width <= 0:
|
||||
return 1
|
||||
|
||||
# 计算每行可容纳的项目数量
|
||||
available_width = parent_width - spacing # 减去左边距
|
||||
items_per_row = max(1, int(available_width / (item_width + spacing)))
|
||||
|
||||
return items_per_row
|
||||
|
||||
# 预缓存的图片缓存,减少重复加载
|
||||
_pixmap_cache = {}
|
||||
_pixmap_cache_max_size = 50 # 最多缓存50张图片
|
||||
_pixmap_cache_lru = [] # 最近最少使用列表,用于清理缓存
|
||||
|
||||
def get_pixmap(image_path, width, height):
|
||||
"""
|
||||
从缓存获取QPixmap或创建新的
|
||||
|
||||
Args:
|
||||
image_path: 图片路径
|
||||
width: 所需宽度
|
||||
height: 所需高度
|
||||
|
||||
Returns:
|
||||
QPixmap: 图片对象
|
||||
"""
|
||||
cache_key = f"{image_path}_{width}_{height}"
|
||||
|
||||
# 检查缓存
|
||||
if cache_key in _pixmap_cache:
|
||||
# 更新LRU列表
|
||||
global _pixmap_cache_lru
|
||||
if cache_key in _pixmap_cache_lru:
|
||||
_pixmap_cache_lru.remove(cache_key)
|
||||
_pixmap_cache_lru.append(cache_key)
|
||||
return _pixmap_cache[cache_key]
|
||||
|
||||
try:
|
||||
# 加载原始图片
|
||||
pixmap = QtGui.QPixmap(image_path)
|
||||
|
||||
if not pixmap.isNull():
|
||||
# 缩放图片
|
||||
if width > 0 and height > 0:
|
||||
pixmap = pixmap.scaled(width, height, QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation)
|
||||
|
||||
# 缓存清理 - 如果超出最大缓存大小,删除最不常用的项目
|
||||
global _pixmap_cache_max_size
|
||||
if len(_pixmap_cache) >= _pixmap_cache_max_size and _pixmap_cache_lru:
|
||||
oldest_key = _pixmap_cache_lru.pop(0)
|
||||
if oldest_key in _pixmap_cache:
|
||||
del _pixmap_cache[oldest_key]
|
||||
|
||||
# 存入缓存
|
||||
_pixmap_cache[cache_key] = pixmap
|
||||
_pixmap_cache_lru.append(cache_key)
|
||||
return pixmap
|
||||
else:
|
||||
# 创建一个纯色背景作为替代
|
||||
fallback_pixmap = QtGui.QPixmap(width, height)
|
||||
fallback_pixmap.fill(QtGui.QColor(60, 60, 60))
|
||||
return fallback_pixmap
|
||||
except Exception as e:
|
||||
print(f"加载图像失败 ({image_path}): {str(e)}")
|
||||
fallback_pixmap = QtGui.QPixmap(width, height)
|
||||
fallback_pixmap.fill(QtGui.QColor(60, 60, 60))
|
||||
return fallback_pixmap
|
||||
|
||||
def create_dna_preview_button(dna_info, item_size, on_click_callback):
|
||||
"""
|
||||
创建DNA预览按钮
|
||||
|
||||
Args:
|
||||
dna_info (dict): DNA文件信息
|
||||
item_size (tuple): 按钮尺寸 (宽, 高)
|
||||
on_click_callback (function): 点击回调函数
|
||||
|
||||
Returns:
|
||||
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")
|
||||
|
||||
# 创建垂直布局
|
||||
layout = QtWidgets.QVBoxLayout(button)
|
||||
layout.setContentsMargins(0, 0, 0, 0)
|
||||
layout.setSpacing(2)
|
||||
|
||||
# 创建图像标签
|
||||
image_label = QtWidgets.QLabel()
|
||||
image_label.setObjectName(f"image_{dna_info['name']}")
|
||||
image_label.setFixedSize(item_size[0], item_size[0]) # 正方形图像区域
|
||||
image_label.setScaledContents(True)
|
||||
|
||||
# 使用预缓存加载图像
|
||||
pixmap = get_pixmap(dna_info['image_path'], item_size[0], item_size[0])
|
||||
image_label.setPixmap(pixmap)
|
||||
|
||||
# 创建名称标签
|
||||
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: rgba(0, 0, 0, 128); padding: 2px;")
|
||||
|
||||
# 添加到布局
|
||||
layout.addWidget(image_label)
|
||||
layout.addWidget(name_label)
|
||||
|
||||
# 设置按钮数据
|
||||
button.setProperty("dna_path", dna_info['dna_path'])
|
||||
|
||||
# 连接点击信号
|
||||
button.clicked.connect(lambda: on_click_callback(dna_info['dna_path']))
|
||||
|
||||
return 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])
|
||||
if on_click_callback:
|
||||
fallback_button.clicked.connect(lambda: on_click_callback(dna_info.get('dna_path', '')))
|
||||
return fallback_button
|
||||
|
||||
# 缓存上一次的布局信息,避免不必要的重新计算
|
||||
_last_layout_info = {
|
||||
"parent_width": 0,
|
||||
"item_size": (0, 0),
|
||||
"spacing": 0,
|
||||
"items_per_row": 0
|
||||
}
|
||||
|
||||
def load_dna_preview_buttons(ui_instance):
|
||||
"""
|
||||
为UI加载DNA预览按钮
|
||||
|
||||
Args:
|
||||
ui_instance: UI实例
|
||||
"""
|
||||
try:
|
||||
# 检查UI实例是否有效
|
||||
if not ui_instance or not hasattr(ui_instance, 'controls'):
|
||||
print("无效的UI实例,无法加载DNA预览按钮")
|
||||
return False
|
||||
|
||||
# 获取DNA文件列表
|
||||
dna_files = ui_instance.dna_files
|
||||
|
||||
# 检查是否有DNA文件
|
||||
if not dna_files:
|
||||
# 如果还没有加载DNA文件,则先加载
|
||||
ui_instance.dna_files = get_dna_files()
|
||||
dna_files = ui_instance.dna_files
|
||||
if not dna_files:
|
||||
print("没有找到DNA文件,无法加载预览按钮")
|
||||
if 'presets_count_label' in ui_instance.controls:
|
||||
ui_instance.controls['presets_count_label'].setText("0")
|
||||
return False
|
||||
|
||||
# 更新预设数量标签
|
||||
if 'presets_count_label' in ui_instance.controls:
|
||||
ui_instance.controls['presets_count_label'].setText(str(len(dna_files)))
|
||||
|
||||
# 获取滚动区域宽度
|
||||
if 'presets_content' in ui_instance.controls:
|
||||
scroll_width = ui_instance.controls['presets_content'].width()
|
||||
else:
|
||||
scroll_width = 400 # 默认宽度
|
||||
|
||||
# 更新DNA网格布局
|
||||
update_dna_grid_layout(
|
||||
ui_instance.controls["presets_flow_layout"],
|
||||
scroll_width,
|
||||
ui_instance.dna_button_size,
|
||||
10, # 间距
|
||||
dna_files,
|
||||
lambda dna_path: on_dna_button_clicked(dna_path, ui_instance)
|
||||
)
|
||||
|
||||
return True
|
||||
except Exception as e:
|
||||
import traceback
|
||||
print(f"加载DNA预览按钮失败: {str(e)}")
|
||||
traceback.print_exc()
|
||||
return False
|
||||
|
||||
def update_dna_grid_layout(flow_layout, parent_width, item_size, spacing, dna_files, on_dna_clicked):
|
||||
"""
|
||||
更新DNA网格布局,根据父容器宽度动态调整每行显示的DNA项目数量
|
||||
|
||||
Args:
|
||||
flow_layout (QGridLayout): 网格布局
|
||||
parent_width (int): 父容器宽度
|
||||
item_size (tuple): 项目尺寸 (宽, 高)
|
||||
spacing (int): 项目间的间距
|
||||
dna_files (list): DNA文件信息列表
|
||||
on_dna_clicked (function): DNA按钮点击回调函数
|
||||
"""
|
||||
try:
|
||||
# 检查参数有效性
|
||||
if flow_layout is None:
|
||||
print("错误: flow_layout 为空")
|
||||
return
|
||||
|
||||
if not dna_files:
|
||||
print("警告: 没有DNA文件可以显示")
|
||||
return
|
||||
|
||||
if parent_width <= 0:
|
||||
print(f"警告: 父容器宽度无效 ({parent_width})")
|
||||
parent_width = 400 # 使用默认宽度
|
||||
|
||||
global _last_layout_info
|
||||
|
||||
# 计算每行可容纳的项目数量
|
||||
items_per_row = calculate_grid_layout(parent_width, item_size[0], spacing)
|
||||
|
||||
# 如果布局信息与上次相同,则不需要重新布局
|
||||
if (_last_layout_info["parent_width"] == parent_width and
|
||||
_last_layout_info["item_size"] == item_size and
|
||||
_last_layout_info["spacing"] == spacing and
|
||||
_last_layout_info["items_per_row"] == items_per_row and
|
||||
flow_layout.count() > 0):
|
||||
return
|
||||
|
||||
# 更新布局信息缓存
|
||||
_last_layout_info = {
|
||||
"parent_width": parent_width,
|
||||
"item_size": item_size,
|
||||
"spacing": spacing,
|
||||
"items_per_row": items_per_row
|
||||
}
|
||||
|
||||
print(f"布局信息: 宽度 = {parent_width}, 项目宽度 = {item_size[0]}, 每行项目数 = {items_per_row}")
|
||||
|
||||
# 先移除所有现有控件
|
||||
for i in reversed(range(flow_layout.count())):
|
||||
item = flow_layout.itemAt(i)
|
||||
if item and item.widget():
|
||||
item.widget().setParent(None) # 从父窗口分离
|
||||
item.widget().deleteLater() # 稍后删除控件
|
||||
|
||||
# 重新添加DNA预览按钮
|
||||
for i, dna_info in enumerate(dna_files):
|
||||
try:
|
||||
row = i // items_per_row
|
||||
col = i % items_per_row
|
||||
|
||||
# 创建DNA预览按钮
|
||||
dna_button = create_dna_preview_button(dna_info, item_size, on_dna_clicked)
|
||||
|
||||
# 添加到网格布局
|
||||
flow_layout.addWidget(dna_button, row, col)
|
||||
except Exception as e:
|
||||
print(f"添加DNA按钮失败 ({dna_info['name']}): {str(e)}")
|
||||
except Exception as e:
|
||||
print(f"更新DNA网格布局失败: {str(e)}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
# 保存上次调整大小的时间,用于限制调整频率
|
||||
_last_resize_time = 0
|
||||
_resize_throttle = 200 # 毫秒
|
||||
|
||||
def on_presets_content_resize(event, ui_instance):
|
||||
"""
|
||||
预设内容区域大小变化事件,限制更新频率以提高性能
|
||||
|
||||
Args:
|
||||
event: 调整大小事件
|
||||
ui_instance: UI实例
|
||||
"""
|
||||
try:
|
||||
# 检查UI实例是否有效
|
||||
if not ui_instance or not hasattr(ui_instance, 'controls') or "presets_content" not in ui_instance.controls:
|
||||
# 如果UI实例无效,只调用原始的resizeEvent
|
||||
QtWidgets.QWidget.resizeEvent(event.widget(), event)
|
||||
return
|
||||
|
||||
global _last_resize_time
|
||||
|
||||
# 调用父类的resizeEvent
|
||||
QtWidgets.QWidget.resizeEvent(ui_instance.controls["presets_content"], event)
|
||||
|
||||
# 获取当前时间
|
||||
current_time = QtCore.QTime.currentTime().msecsSinceStartOfDay()
|
||||
|
||||
# 如果距离上次更新不足阈值时间,则跳过更新
|
||||
if current_time - _last_resize_time < _resize_throttle:
|
||||
return
|
||||
|
||||
# 更新上次调整时间
|
||||
_last_resize_time = current_time
|
||||
|
||||
# 确保所有必要的控件和属性都存在
|
||||
required_keys = ["presets_flow_layout"]
|
||||
required_attrs = ["dna_button_size", "dna_files"]
|
||||
|
||||
for key in required_keys:
|
||||
if key not in ui_instance.controls:
|
||||
print(f"警告: '{key}' 未在UI控件中找到")
|
||||
return
|
||||
|
||||
for attr in required_attrs:
|
||||
if not hasattr(ui_instance, attr):
|
||||
print(f"警告: '{attr}' 属性未在UI实例中找到")
|
||||
return
|
||||
|
||||
# 更新DNA网格布局
|
||||
update_dna_grid_layout(
|
||||
ui_instance.controls["presets_flow_layout"],
|
||||
event.size().width(),
|
||||
ui_instance.dna_button_size,
|
||||
10, # 间距
|
||||
ui_instance.dna_files,
|
||||
lambda dna_path: on_dna_button_clicked(dna_path, ui_instance)
|
||||
)
|
||||
except Exception as e:
|
||||
import traceback
|
||||
print(f"调整DNA预览布局失败: {str(e)}")
|
||||
traceback.print_exc()
|
||||
|
||||
def on_dna_button_clicked(dna_path, ui_instance):
|
||||
"""
|
||||
DNA按钮点击事件
|
||||
|
||||
Args:
|
||||
dna_path: DNA文件路径
|
||||
ui_instance: UI实例
|
||||
"""
|
||||
try:
|
||||
# 检查UI实例是否有效
|
||||
if not ui_instance or not hasattr(ui_instance, 'controls'):
|
||||
print("警告: UI实例无效,无法更新DNA路径")
|
||||
# 仍然尝试加载DNA文件,即使无法更新UI
|
||||
load_selected_dna(dna_path)
|
||||
return
|
||||
|
||||
# 加载选中的DNA文件
|
||||
load_selected_dna(dna_path, ui_instance)
|
||||
|
||||
# 更新UI中的DNA路径输入框
|
||||
if "presets_dna_input" in ui_instance.controls:
|
||||
ui_instance.controls["presets_dna_input"].setText(dna_path)
|
||||
else:
|
||||
print("警告: 'presets_dna_input' 未创建")
|
||||
except Exception as e:
|
||||
import traceback
|
||||
print(f"点击DNA按钮处理失败: {str(e)}")
|
||||
traceback.print_exc()
|
||||
|
||||
#------------------------------------ UI UTILITIES ------------------------------------
|
||||
def browse_file(parent_widget, title, line_edit, file_type=None):
|
||||
"""
|
||||
@@ -265,4 +736,14 @@ def build_rigging(*args):
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"构建绑定系统失败: {str(e)}")
|
||||
return False
|
||||
return False
|
||||
|
||||
def clear_pixmap_cache():
|
||||
"""
|
||||
清除图片缓存
|
||||
在不再需要缓存时调用,例如关闭窗口时
|
||||
"""
|
||||
global _pixmap_cache, _pixmap_cache_lru
|
||||
_pixmap_cache.clear()
|
||||
_pixmap_cache_lru.clear()
|
||||
print("图片缓存已清除")
|
Reference in New Issue
Block a user