405 lines
13 KiB
Python
405 lines
13 KiB
Python
"""
|
|
图标管理器GUI工具
|
|
|
|
提供图形界面来管理和查看图标:
|
|
- 显示所有可用图标
|
|
- 图标预览
|
|
- 图标信息
|
|
- 图标刷新
|
|
"""
|
|
import os
|
|
from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QPushButton,
|
|
QListWidget, QListWidgetItem, QLabel, QGroupBox,
|
|
QTextEdit, QSplitter, QDialog, QDialogButtonBox,
|
|
QFileDialog, QMessageBox, QScrollArea, QGridLayout)
|
|
from PyQt5.QtGui import QIcon, QPixmap, QFont
|
|
from PyQt5.QtCore import Qt, QSize
|
|
|
|
from ui.icon_manager import get_icon_manager
|
|
|
|
|
|
class IconPreviewWidget(QWidget):
|
|
"""图标预览控件"""
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.setupUI()
|
|
|
|
def setupUI(self):
|
|
"""设置UI"""
|
|
layout = QVBoxLayout(self)
|
|
|
|
# 图标显示区域
|
|
self.icon_label = QLabel()
|
|
self.icon_label.setAlignment(Qt.AlignCenter)
|
|
self.icon_label.setStyleSheet("""
|
|
QLabel {
|
|
border: 2px dashed #8b5cf6;
|
|
border-radius: 8px;
|
|
background-color: #2d2d44;
|
|
color: #e0e0ff;
|
|
min-height: 100px;
|
|
margin: 10px;
|
|
}
|
|
""")
|
|
self.icon_label.setText("选择图标查看预览")
|
|
layout.addWidget(self.icon_label)
|
|
|
|
# 图标信息
|
|
self.info_label = QLabel()
|
|
self.info_label.setStyleSheet("""
|
|
QLabel {
|
|
background-color: #252538;
|
|
color: #e0e0ff;
|
|
padding: 10px;
|
|
border-radius: 4px;
|
|
font-family: monospace;
|
|
}
|
|
""")
|
|
self.info_label.setText("图标信息将在此显示")
|
|
layout.addWidget(self.info_label)
|
|
|
|
def showIcon(self, icon_name: str, icon: QIcon):
|
|
"""显示图标"""
|
|
if not icon.isNull():
|
|
# 显示不同尺寸的图标
|
|
sizes = [16, 24, 32, 48, 64]
|
|
pixmaps = []
|
|
|
|
# 创建组合图标显示
|
|
for size in sizes:
|
|
pixmap = icon.pixmap(QSize(size, size))
|
|
if not pixmap.isNull():
|
|
pixmaps.append((size, pixmap))
|
|
|
|
if pixmaps:
|
|
# 创建合成图片显示多个尺寸
|
|
total_width = sum(size for size, _ in pixmaps) + 20 * (len(pixmaps) - 1)
|
|
max_height = max(size for size, _ in pixmaps)
|
|
|
|
combined_pixmap = QPixmap(total_width, max_height + 40)
|
|
combined_pixmap.fill(Qt.transparent)
|
|
|
|
from PyQt5.QtGui import QPainter, QPen
|
|
painter = QPainter(combined_pixmap)
|
|
|
|
x = 0
|
|
for size, pixmap in pixmaps:
|
|
# 绘制图标
|
|
y = (max_height - size) // 2
|
|
painter.drawPixmap(x, y, pixmap)
|
|
|
|
# 绘制尺寸标签
|
|
painter.setPen(QPen(Qt.white))
|
|
painter.drawText(x, max_height + 15, f"{size}x{size}")
|
|
|
|
x += size + 20
|
|
|
|
painter.end()
|
|
|
|
self.icon_label.setPixmap(combined_pixmap)
|
|
else:
|
|
self.icon_label.setText("无法加载图标")
|
|
else:
|
|
self.icon_label.setText("图标无效")
|
|
|
|
# 更新信息
|
|
info_text = f"图标名称: {icon_name}\n"
|
|
info_text += f"图标有效: {'是' if not icon.isNull() else '否'}\n"
|
|
|
|
# 获取图标管理器信息
|
|
icon_manager = get_icon_manager()
|
|
icon_path = icon_manager.get_icon_path(icon_name)
|
|
if icon_path:
|
|
info_text += f"文件路径: {icon_path}\n"
|
|
if os.path.exists(icon_path):
|
|
size = os.path.getsize(icon_path)
|
|
info_text += f"文件大小: {size} bytes\n"
|
|
|
|
# 获取可用尺寸
|
|
if not icon.isNull():
|
|
available_sizes = icon.availableSizes()
|
|
if available_sizes:
|
|
sizes_text = ", ".join(f"{s.width()}x{s.height()}" for s in available_sizes)
|
|
info_text += f"可用尺寸: {sizes_text}\n"
|
|
|
|
self.info_label.setText(info_text)
|
|
|
|
|
|
class IconManagerDialog(QDialog):
|
|
"""图标管理器对话框"""
|
|
|
|
def __init__(self, parent=None):
|
|
super().__init__(parent)
|
|
self.icon_manager = get_icon_manager()
|
|
self.setupUI()
|
|
self.loadIcons()
|
|
|
|
def setupUI(self):
|
|
"""设置UI"""
|
|
self.setWindowTitle("图标管理器")
|
|
self.setModal(False)
|
|
self.resize(800, 600)
|
|
|
|
# 设置样式
|
|
self.setStyleSheet("""
|
|
QDialog {
|
|
background-color: #1e1e2e;
|
|
color: #e0e0ff;
|
|
}
|
|
QListWidget {
|
|
background-color: #252538;
|
|
color: #e0e0ff;
|
|
border: 1px solid #3a3a4a;
|
|
border-radius: 4px;
|
|
alternate-background-color: #2d2d44;
|
|
}
|
|
QListWidget::item {
|
|
padding: 8px;
|
|
border-bottom: 1px solid #3a3a4a;
|
|
}
|
|
QListWidget::item:hover {
|
|
background-color: #3a3a4a;
|
|
}
|
|
QListWidget::item:selected {
|
|
background-color: rgba(139, 92, 246, 100);
|
|
color: white;
|
|
}
|
|
QPushButton {
|
|
background-color: #8b5cf6;
|
|
color: white;
|
|
border: none;
|
|
padding: 8px 16px;
|
|
border-radius: 4px;
|
|
font-weight: 500;
|
|
}
|
|
QPushButton:hover {
|
|
background-color: #7c3aed;
|
|
}
|
|
QPushButton:pressed {
|
|
background-color: #6d28d9;
|
|
}
|
|
QGroupBox {
|
|
background-color: #252538;
|
|
border: 1px solid #3a3a4a;
|
|
border-radius: 6px;
|
|
margin-top: 1ex;
|
|
color: #e0e0ff;
|
|
font-weight: 500;
|
|
padding-top: 10px;
|
|
}
|
|
QGroupBox::title {
|
|
subline-offset: -2px;
|
|
padding: 0 8px;
|
|
color: #c0c0e0;
|
|
font-weight: 500;
|
|
}
|
|
QTextEdit {
|
|
background-color: #252538;
|
|
color: #e0e0ff;
|
|
border: 1px solid #3a3a4a;
|
|
border-radius: 4px;
|
|
font-family: monospace;
|
|
}
|
|
""")
|
|
|
|
layout = QVBoxLayout(self)
|
|
|
|
# 顶部按钮栏
|
|
button_layout = QHBoxLayout()
|
|
|
|
self.refresh_btn = QPushButton("刷新图标")
|
|
self.refresh_btn.clicked.connect(self.refreshIcons)
|
|
button_layout.addWidget(self.refresh_btn)
|
|
|
|
self.add_icon_btn = QPushButton("添加图标")
|
|
self.add_icon_btn.clicked.connect(self.addIcon)
|
|
button_layout.addWidget(self.add_icon_btn)
|
|
|
|
self.debug_btn = QPushButton("调试信息")
|
|
self.debug_btn.clicked.connect(self.showDebugInfo)
|
|
button_layout.addWidget(self.debug_btn)
|
|
|
|
button_layout.addStretch()
|
|
layout.addLayout(button_layout)
|
|
|
|
# 主分割器
|
|
splitter = QSplitter(Qt.Horizontal)
|
|
|
|
# 左侧:图标列表
|
|
left_widget = QWidget()
|
|
left_layout = QVBoxLayout(left_widget)
|
|
|
|
list_group = QGroupBox("可用图标")
|
|
list_layout = QVBoxLayout(list_group)
|
|
|
|
self.icon_list = QListWidget()
|
|
self.icon_list.itemSelectionChanged.connect(self.onIconSelected)
|
|
list_layout.addWidget(self.icon_list)
|
|
|
|
left_layout.addWidget(list_group)
|
|
splitter.addWidget(left_widget)
|
|
|
|
# 右侧:图标预览
|
|
right_widget = QWidget()
|
|
right_layout = QVBoxLayout(right_widget)
|
|
|
|
preview_group = QGroupBox("图标预览")
|
|
preview_layout = QVBoxLayout(preview_group)
|
|
|
|
self.preview_widget = IconPreviewWidget()
|
|
preview_layout.addWidget(self.preview_widget)
|
|
|
|
right_layout.addWidget(preview_group)
|
|
splitter.addWidget(right_widget)
|
|
|
|
# 设置分割器比例
|
|
splitter.setSizes([300, 500])
|
|
layout.addWidget(splitter)
|
|
|
|
# 底部按钮
|
|
button_box = QDialogButtonBox(QDialogButtonBox.Close)
|
|
button_box.rejected.connect(self.close)
|
|
layout.addWidget(button_box)
|
|
|
|
def loadIcons(self):
|
|
"""加载图标列表"""
|
|
self.icon_list.clear()
|
|
|
|
available_icons = self.icon_manager.get_available_icons()
|
|
|
|
for icon_name in available_icons:
|
|
item = QListWidgetItem()
|
|
|
|
# 获取图标
|
|
icon = self.icon_manager.get_icon(icon_name, QSize(24, 24))
|
|
|
|
# 设置图标和文本
|
|
if not icon.isNull():
|
|
item.setIcon(icon)
|
|
item.setText(f"🎨 {icon_name}")
|
|
else:
|
|
item.setText(f"❌ {icon_name}")
|
|
|
|
item.setData(Qt.UserRole, icon_name)
|
|
self.icon_list.addItem(item)
|
|
|
|
print(f"📊 加载了 {len(available_icons)} 个图标")
|
|
|
|
def onIconSelected(self):
|
|
"""当选择图标时"""
|
|
current_item = self.icon_list.currentItem()
|
|
if current_item:
|
|
icon_name = current_item.data(Qt.UserRole)
|
|
icon = self.icon_manager.get_icon(icon_name)
|
|
self.preview_widget.showIcon(icon_name, icon)
|
|
|
|
def refreshIcons(self):
|
|
"""刷新图标"""
|
|
print("🔄 刷新图标缓存...")
|
|
self.icon_manager.refresh_cache()
|
|
self.loadIcons()
|
|
QMessageBox.information(self, "完成", "图标缓存已刷新")
|
|
|
|
def addIcon(self):
|
|
"""添加新图标"""
|
|
file_path, _ = QFileDialog.getOpenFileName(
|
|
self,
|
|
"选择图标文件",
|
|
"",
|
|
"图像文件 (*.png *.jpg *.jpeg *.svg *.ico);;所有文件 (*)"
|
|
)
|
|
|
|
if file_path:
|
|
# 获取文件名作为图标名称
|
|
file_name = os.path.basename(file_path)
|
|
icon_name = os.path.splitext(file_name)[0]
|
|
|
|
# 复制文件到图标目录
|
|
import shutil
|
|
target_path = os.path.join(self.icon_manager.icon_directory, file_name)
|
|
|
|
try:
|
|
shutil.copy2(file_path, target_path)
|
|
|
|
# 添加到缓存
|
|
success = self.icon_manager.add_icon(icon_name, target_path)
|
|
|
|
if success:
|
|
QMessageBox.information(self, "成功", f"图标 '{icon_name}' 已添加")
|
|
self.loadIcons()
|
|
else:
|
|
QMessageBox.warning(self, "失败", "添加图标失败")
|
|
|
|
except Exception as e:
|
|
QMessageBox.critical(self, "错误", f"复制文件失败:\n{str(e)}")
|
|
|
|
def showDebugInfo(self):
|
|
"""显示调试信息"""
|
|
debug_dialog = QDialog(self)
|
|
debug_dialog.setWindowTitle("图标管理器调试信息")
|
|
debug_dialog.resize(600, 400)
|
|
|
|
layout = QVBoxLayout(debug_dialog)
|
|
|
|
text_edit = QTextEdit()
|
|
text_edit.setFont(QFont("Consolas", 10))
|
|
|
|
# 获取调试信息
|
|
info = self.icon_manager.get_cache_info()
|
|
debug_text = "图标管理器调试信息\n"
|
|
debug_text += "=" * 50 + "\n\n"
|
|
debug_text += f"图标目录: {info['icon_directory']}\n"
|
|
debug_text += f"目录存在: {os.path.exists(info['icon_directory'])}\n"
|
|
debug_text += f"缓存图标数: {info['cached_icons']}\n"
|
|
debug_text += f"可用图标数: {info['available_icons']}\n\n"
|
|
|
|
debug_text += "已缓存的图标:\n"
|
|
for key in info['cache_keys']:
|
|
debug_text += f" - {key}\n"
|
|
|
|
debug_text += "\n图标目录内容:\n"
|
|
if os.path.exists(info['icon_directory']):
|
|
for file_name in os.listdir(info['icon_directory']):
|
|
file_path = os.path.join(info['icon_directory'], file_name)
|
|
if os.path.isfile(file_path):
|
|
size = os.path.getsize(file_path)
|
|
debug_text += f" - {file_name} ({size} bytes)\n"
|
|
else:
|
|
debug_text += " 目录不存在\n"
|
|
|
|
text_edit.setPlainText(debug_text)
|
|
layout.addWidget(text_edit)
|
|
|
|
button_box = QDialogButtonBox(QDialogButtonBox.Close)
|
|
button_box.rejected.connect(debug_dialog.close)
|
|
layout.addWidget(button_box)
|
|
|
|
debug_dialog.exec_()
|
|
|
|
|
|
def show_icon_manager(parent=None):
|
|
"""显示图标管理器对话框"""
|
|
dialog = IconManagerDialog(parent)
|
|
dialog.show()
|
|
return dialog
|
|
|
|
|
|
if __name__ == "__main__":
|
|
from PyQt5.QtWidgets import QApplication
|
|
import sys
|
|
|
|
app = QApplication(sys.argv)
|
|
|
|
# 设置全局样式
|
|
app.setStyleSheet("""
|
|
QApplication {
|
|
background-color: #1e1e2e;
|
|
color: #e0e0ff;
|
|
}
|
|
""")
|
|
|
|
dialog = IconManagerDialog()
|
|
dialog.show()
|
|
|
|
sys.exit(app.exec_()) |