Update
This commit is contained in:
@@ -132,6 +132,7 @@ class FlowLayout(QtWidgets.QLayout):
|
||||
item_width = item.sizeHint().width()
|
||||
item_height = item.sizeHint().height()
|
||||
|
||||
# 检查是否需要换行 - 当前项放不下时
|
||||
next_x = x + item_width + spacing
|
||||
|
||||
if next_x - spacing > rect.right() and line_height > 0:
|
||||
@@ -167,7 +168,7 @@ class RiggingUI(ui_utils.BaseUI):
|
||||
|
||||
# 初始化DNA文件列表和按钮尺寸
|
||||
self.dna_files = []
|
||||
self.dna_button_size = (140, 170) # 增加按钮尺寸,提供更好的视觉效果
|
||||
self.dna_button_size = (90, 120) # 保持3:4的宽高比例
|
||||
|
||||
# 初始化UI
|
||||
self.create_widgets()
|
||||
@@ -229,48 +230,87 @@ class RiggingUI(ui_utils.BaseUI):
|
||||
self.controls["presets_scroll_area"] = QtWidgets.QScrollArea()
|
||||
self.controls["presets_scroll_area"].setWidgetResizable(True)
|
||||
self.controls["presets_scroll_area"].setObjectName("presetsScrollArea")
|
||||
self.controls["presets_scroll_area"].setMinimumHeight(400) # 大幅增加最小高度,确保能容纳多行按钮
|
||||
self.controls["presets_scroll_area"].setMinimumWidth(600) # 设置最小宽度,确保有足够空间显示按钮
|
||||
|
||||
# 预设内容区域
|
||||
self.controls["presets_content"] = QtWidgets.QWidget()
|
||||
self.controls["presets_content"].setObjectName("presetsContent")
|
||||
self.controls["presets_content"].setMinimumHeight(380) # 保持内容区域最小高度
|
||||
self.controls["presets_content"].setStyleSheet("""
|
||||
#presetsContent {
|
||||
background-color: #252526;
|
||||
}
|
||||
""")
|
||||
|
||||
# 使用流式布局替代原来的网格布局
|
||||
self.controls["presets_flow_layout"] = FlowLayout(self.controls["presets_content"])
|
||||
self.controls["presets_flow_layout"].setObjectName("presetsFlowLayout")
|
||||
self.controls["presets_flow_layout"].setContentsMargins(10, 10, 10, 10)
|
||||
self.controls["presets_flow_layout"].setSpacing(15) # 固定间距
|
||||
self.controls["presets_flow_layout"].setContentsMargins(10, 10, 10, 5) # 进一步减小底部边距
|
||||
self.controls["presets_flow_layout"].setSpacing(10) # 保持按钮间距
|
||||
|
||||
# 设置滚动区域内容
|
||||
self.controls["presets_scroll_area"].setWidget(self.controls["presets_content"])
|
||||
|
||||
# 创建布局分隔器,添加垂直空间和分隔线
|
||||
self.controls["presets_separator"] = QtWidgets.QFrame()
|
||||
self.controls["presets_separator"].setFrameShape(QtWidgets.QFrame.HLine)
|
||||
self.controls["presets_separator"].setFrameShadow(QtWidgets.QFrame.Sunken)
|
||||
self.controls["presets_separator"].setFixedHeight(1) # 减小分隔线高度
|
||||
self.controls["presets_separator"].setStyleSheet("background-color: #444444;")
|
||||
|
||||
# 预设底部滑块和按钮
|
||||
self.controls["presets_slider_layout"] = QtWidgets.QHBoxLayout()
|
||||
self.controls["presets_slider_layout"].setContentsMargins(5, 5, 5, 5)
|
||||
self.controls["presets_slider_layout"].setSpacing(5)
|
||||
self.controls["presets_slider_layout"].setContentsMargins(3, 0, 3, 0) # 减小左右内边距
|
||||
self.controls["presets_slider_layout"].setSpacing(4) # 减小间距
|
||||
|
||||
# 数量显示
|
||||
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;")
|
||||
self.controls["presets_count_label"].setStyleSheet("font-weight: bold; font-size: 12px;")
|
||||
self.controls["presets_count_label"].setFixedWidth(40) # 增加宽度
|
||||
|
||||
# 滑块 - 用于调整预览图大小
|
||||
self.controls["presets_slider"] = QtWidgets.QSlider(QtCore.Qt.Horizontal)
|
||||
self.controls["presets_slider"].setObjectName("presetsSlider")
|
||||
self.controls["presets_slider"].setMinimum(20) # 最小值
|
||||
self.controls["presets_slider"].setMaximum(100) # 最大值
|
||||
self.controls["presets_slider"].setValue(60) # 默认值
|
||||
self.controls["presets_slider"].setMinimum(70) # 最小值70,对应缩放因子约0.8
|
||||
self.controls["presets_slider"].setMaximum(130) # 最大值130,对应缩放因子约1.2
|
||||
self.controls["presets_slider"].setValue(100) # 中间值100,对应缩放因子1.0
|
||||
self.controls["presets_slider"].setToolTip("调整预览图大小")
|
||||
self.controls["presets_slider"].setFixedHeight(22) # 设置固定高度使滑块更粗
|
||||
self.controls["presets_slider"].setStyleSheet("""
|
||||
QSlider::groove:horizontal {
|
||||
border: 1px solid #999999;
|
||||
height: 8px;
|
||||
background: #3E3E42;
|
||||
margin: 2px 0;
|
||||
border-radius: 4px;
|
||||
}
|
||||
QSlider::handle:horizontal {
|
||||
background: #007ACC;
|
||||
border: 1px solid #5AB2F5;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin: -5px 0;
|
||||
border-radius: 8px;
|
||||
}
|
||||
QSlider::handle:horizontal:hover {
|
||||
background: #1C97EA;
|
||||
}
|
||||
""")
|
||||
|
||||
# 导出预设按钮
|
||||
self.buttons["export_presets"] = QtWidgets.QPushButton(TEXT("export_presets", "导出预设"))
|
||||
self.buttons["export_presets"].setObjectName("exportPresetsButton")
|
||||
self.buttons["export_presets"].setIcon(ui_utils.load_icon("export"))
|
||||
self.buttons["export_presets"].setFixedHeight(28) # 设置固定高度
|
||||
|
||||
# 导入预设按钮
|
||||
self.buttons["import_presets"] = QtWidgets.QPushButton(TEXT("import_presets", "导入预设"))
|
||||
self.buttons["import_presets"].setObjectName("importPresetsButton")
|
||||
self.buttons["import_presets"].setIcon(ui_utils.load_icon("import"))
|
||||
self.buttons["import_presets"].setFixedHeight(28) # 设置固定高度
|
||||
|
||||
# 添加到滑块布局
|
||||
self.controls["presets_slider_layout"].addWidget(self.controls["presets_count_label"])
|
||||
@@ -440,14 +480,36 @@ class RiggingUI(ui_utils.BaseUI):
|
||||
|
||||
# Presets 组布局
|
||||
presets_group_layout = QtWidgets.QVBoxLayout(self.controls["presets_group"])
|
||||
presets_group_layout.setContentsMargins(5, 5, 5, 5)
|
||||
presets_group_layout.setSpacing(5)
|
||||
presets_group_layout.setContentsMargins(5, 5, 5, 0) # 移除底部内边距
|
||||
presets_group_layout.setSpacing(0) # 移除内部间距
|
||||
|
||||
# 添加预设滚动区域
|
||||
presets_group_layout.addWidget(self.controls["presets_scroll_area"])
|
||||
|
||||
# 添加预设底部滑块布局
|
||||
presets_group_layout.addLayout(self.controls["presets_slider_layout"])
|
||||
# 添加分隔线
|
||||
self.controls["presets_separator"].setFixedHeight(1) # 减小分隔线高度
|
||||
self.controls["presets_separator"].setStyleSheet("background-color: #444444;")
|
||||
presets_group_layout.addWidget(self.controls["presets_separator"])
|
||||
|
||||
# 创建滑块容器,与上方内容无缝对接
|
||||
slider_container = QtWidgets.QWidget()
|
||||
slider_container.setObjectName("sliderContainer")
|
||||
slider_container.setFixedHeight(34) # 高度更小
|
||||
slider_container.setStyleSheet("""
|
||||
#sliderContainer {
|
||||
background-color: #222222;
|
||||
border-top: 1px solid #444444;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
""")
|
||||
slider_container_layout = QtWidgets.QVBoxLayout(slider_container)
|
||||
slider_container_layout.setContentsMargins(5, 2, 5, 2) # 上下边距更小
|
||||
slider_container_layout.setSpacing(0)
|
||||
slider_container_layout.addLayout(self.controls["presets_slider_layout"])
|
||||
|
||||
# 添加滑块容器到布局
|
||||
presets_group_layout.addWidget(slider_container)
|
||||
|
||||
# 添加Presets组到Presets面板
|
||||
presets_layout.addWidget(self.controls["presets_group"])
|
||||
@@ -560,11 +622,12 @@ class RiggingUI(ui_utils.BaseUI):
|
||||
main_layout.addWidget(self.controls["bottom_buttons_panel"])
|
||||
|
||||
# 设置分割器初始大小
|
||||
self.splitters["main_splitter"].setSizes([400, 100, 200])
|
||||
self.splitters["main_splitter"].setSizes([800, 100, 200]) # 进一步增加顶部预设面板的高度
|
||||
|
||||
# 设置分割器的伸缩因子
|
||||
for i in range(self.splitters["main_splitter"].count()):
|
||||
self.splitters["main_splitter"].setStretchFactor(i, 1)
|
||||
# 设置分割器的伸缩因子 - 让预设面板获得更多空间
|
||||
self.splitters["main_splitter"].setStretchFactor(0, 4) # 预设面板占4份
|
||||
self.splitters["main_splitter"].setStretchFactor(1, 1) # Assets面板占1份
|
||||
self.splitters["main_splitter"].setStretchFactor(2, 1) # Descriptor面板占1份
|
||||
|
||||
# 监听预设内容区域大小变化,更新DNA网格布局
|
||||
self.controls["presets_content"].resizeEvent = lambda event: utils_rigging.on_presets_content_resize(event, self)
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user