294 lines
11 KiB
Python
294 lines
11 KiB
Python
#!/usr/bin/env python3
|
||
# -*- coding: utf-8 -*-
|
||
"""
|
||
侧边栏组件
|
||
"""
|
||
|
||
from PyQt5.QtWidgets import *
|
||
from PyQt5.QtCore import *
|
||
from PyQt5.QtGui import *
|
||
|
||
from data.project_manager import ProjectManager
|
||
from ui.icon_manager import IconManager
|
||
|
||
class Sidebar(QWidget):
|
||
"""侧边栏组件"""
|
||
|
||
# 信号定义
|
||
filter_changed = pyqtSignal(str)
|
||
navigation_changed = pyqtSignal(str, str, str) # 新增信号:(section, item_name, filter_type)
|
||
create_project_requested = pyqtSignal()
|
||
import_project_requested = pyqtSignal()
|
||
|
||
def __init__(self, project_manager: ProjectManager):
|
||
super().__init__()
|
||
self.project_manager = project_manager
|
||
self.current_filter = "overview"
|
||
self.setObjectName("sidebar")
|
||
self.setAttribute(Qt.WA_StyledBackground, True)
|
||
|
||
# 导航项映射:filter_type -> (section, item_name)
|
||
self.nav_mapping = {
|
||
"overview": ("我的项目", "项目概述"),
|
||
"management": ("我的项目", "项目管理"),
|
||
"resource_category": ("资源管理", "资源分类"),
|
||
"resource_management": ("资源管理", "资源管理"),
|
||
"project_settings": ("设置中心", "项目设置"),
|
||
"system_settings": ("设置中心", "系统设置"),
|
||
}
|
||
|
||
self.init_ui()
|
||
self.connect_signals()
|
||
|
||
# 设置固定宽度 - 匹配 Figma 设计规范
|
||
self.setFixedWidth(313)
|
||
|
||
def init_ui(self):
|
||
"""初始化UI"""
|
||
layout = QVBoxLayout(self)
|
||
layout.setContentsMargins(0, 0, 0, 0)
|
||
layout.setSpacing(0)
|
||
|
||
# Logo区域
|
||
self.create_logo_section(layout)
|
||
|
||
# 快速操作区域
|
||
self.create_quick_actions(layout)
|
||
|
||
# 导航菜单
|
||
self.create_navigation_menu(layout)
|
||
|
||
# 底部用户信息
|
||
# layout.addStretch()
|
||
# self.create_user_info(layout)
|
||
|
||
def create_logo_section(self, layout):
|
||
"""创建Logo区域"""
|
||
logo_widget = QWidget()
|
||
logo_widget.setObjectName("logoWidget")
|
||
logo_layout = QHBoxLayout(logo_widget)
|
||
logo_layout.setContentsMargins(37, 32, 46, 24)
|
||
logo_layout.setSpacing(28)
|
||
logo_layout.setAlignment(Qt.AlignCenter)
|
||
|
||
logo_icon = QLabel()
|
||
logo_icon.setObjectName("logoIcon")
|
||
logo_icon.setAlignment(Qt.AlignCenter)
|
||
logo_icon.setFixedSize(80, 80)
|
||
logo_icon.setScaledContents(True)
|
||
if IconManager.icon_exists('logo'):
|
||
logo_icon.setPixmap(IconManager.get_pixmap('logo', QSize(80, 80)))
|
||
else:
|
||
logo_icon.setText("")
|
||
logo_layout.addWidget(logo_icon, alignment=Qt.AlignCenter)
|
||
|
||
logo_text = QLabel("MetaCore")
|
||
logo_text.setObjectName("logoText")
|
||
logo_text.setAlignment(Qt.AlignCenter)
|
||
logo_layout.addWidget(logo_text, 0, Qt.AlignBottom)
|
||
|
||
layout.addWidget(logo_widget)
|
||
|
||
def create_quick_actions(self, layout):
|
||
"""创建快速操作区域"""
|
||
actions_widget = QWidget()
|
||
actions_widget.setObjectName("quickActions")
|
||
actions_layout = QVBoxLayout(actions_widget)
|
||
actions_layout.setContentsMargins(37, 24, 46, 24)
|
||
actions_layout.setSpacing(12)
|
||
|
||
self.create_btn = QPushButton("新建项目")
|
||
# if IconManager.icon_exists('create'):
|
||
# self.create_btn.setIcon(IconManager.get_icon('create'))
|
||
# self.create_btn.setIconSize(QSize(18, 18))
|
||
self.create_btn.setObjectName("createBtn")
|
||
self.create_btn.setCursor(Qt.PointingHandCursor)
|
||
self.create_btn.setMinimumHeight(36)
|
||
self.create_btn.setMaximumHeight(36)
|
||
self.create_btn.clicked.connect(self.create_project_requested.emit)
|
||
actions_layout.addWidget(self.create_btn)
|
||
|
||
self.import_btn = QPushButton("导入项目")
|
||
# if IconManager.icon_exists('import'):
|
||
# self.import_btn.setIcon(IconManager.get_icon('import'))
|
||
# self.import_btn.setIconSize(QSize(18, 18))
|
||
self.import_btn.setObjectName("sidebarImportBtn")
|
||
self.import_btn.setCursor(Qt.PointingHandCursor)
|
||
self.import_btn.setMinimumHeight(36)
|
||
self.import_btn.setMaximumHeight(36)
|
||
self.import_btn.clicked.connect(self.import_project_requested.emit)
|
||
actions_layout.addWidget(self.import_btn)
|
||
|
||
layout.addWidget(actions_widget)
|
||
|
||
def create_navigation_menu(self, layout):
|
||
"""创建导航菜单"""
|
||
# 滚动区域
|
||
scroll_area = QScrollArea()
|
||
scroll_area.setObjectName("navScrollArea") # 设置对象名称
|
||
scroll_area.setWidgetResizable(True) # 自适应内容大小
|
||
scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) # 水平滚动条
|
||
scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) # 垂直滚动条
|
||
|
||
# 导航内容
|
||
nav_widget = QWidget()
|
||
nav_widget.setObjectName("navWidget")
|
||
nav_layout = QVBoxLayout(nav_widget)
|
||
nav_layout.setContentsMargins(0, 10, 0, 0) # 边距:上10px
|
||
nav_layout.setSpacing(10) # 分组间距:10px
|
||
|
||
# 我的项目分组
|
||
self.create_nav_section(nav_layout, "我的项目", [
|
||
("📊", "项目概述", "overview"),
|
||
# ("📋", "项目管理", "management"),
|
||
])
|
||
|
||
# 资源管理分组
|
||
# self.create_nav_section(nav_layout, "资源管理", [
|
||
# ("🏷", "资源分类", "resource_category"),
|
||
# ("📦", "资源管理", "resource_management"),
|
||
# ])
|
||
|
||
# 设置中心分组
|
||
self.create_nav_section(nav_layout, "设置中心", [
|
||
("📁", "项目设置", "project_settings"),
|
||
# ("⚙", "系统设置", "system_settings"),
|
||
])
|
||
|
||
nav_layout.addStretch()
|
||
scroll_area.setWidget(nav_widget)
|
||
layout.addWidget(scroll_area)
|
||
|
||
def create_nav_section(self, layout, title, items):
|
||
"""创建导航分组"""
|
||
# 分组标题
|
||
section_widget = QWidget()
|
||
section_widget.setObjectName("navSection")
|
||
section_layout = QVBoxLayout(section_widget)
|
||
section_layout.setContentsMargins(0, 0, 0, 0)
|
||
section_layout.setSpacing(0)
|
||
|
||
# 标题按钮(可展开/收起)
|
||
title_btn = QPushButton(f" {title}") # 默认有空格
|
||
if IconManager.icon_exists('down'):
|
||
title_btn.setIcon(IconManager.get_icon('down'))
|
||
else:
|
||
title_btn.setText(f"▼ {title}")
|
||
|
||
title_btn.setObjectName("navSectionTitle")
|
||
title_btn.setCheckable(True)
|
||
title_btn.setChecked(True)
|
||
section_layout.addWidget(title_btn)
|
||
|
||
# 子项容器
|
||
items_widget = QWidget()
|
||
items_widget.setObjectName("navItems")
|
||
items_layout = QVBoxLayout(items_widget)
|
||
items_layout.setContentsMargins(50, 10, 0, 0)
|
||
items_layout.setSpacing(10)
|
||
|
||
# 创建导航项
|
||
for icon, text, filter_type in items:
|
||
nav_item = self.create_nav_item(icon, text, filter_type)
|
||
items_layout.addWidget(nav_item, alignment=Qt.AlignLeft)
|
||
|
||
section_layout.addWidget(items_widget)
|
||
|
||
# 展开/收起功能
|
||
def toggle_section():
|
||
is_expanded = title_btn.isChecked()
|
||
items_widget.setVisible(is_expanded)
|
||
if is_expanded:
|
||
if IconManager.icon_exists('down'):
|
||
title_btn.setIcon(IconManager.get_icon('down'))
|
||
# 文本已经在初始化时设置了空格,不需要重新设置
|
||
else:
|
||
title_btn.setText(f"▼ {title}")
|
||
else:
|
||
if IconManager.icon_exists('right'):
|
||
title_btn.setIcon(IconManager.get_icon('right'))
|
||
# 文本已经在初始化时设置了空格,不需要重新设置
|
||
else:
|
||
title_btn.setText(f"▶ {title}")
|
||
|
||
title_btn.clicked.connect(toggle_section)
|
||
layout.addWidget(section_widget)
|
||
|
||
def create_nav_item(self, icon, text, filter_type):
|
||
"""创建导航项"""
|
||
item_btn = QPushButton(text) # 直接使用文本,不显示图标
|
||
|
||
# 隐藏图标,不设置任何图标
|
||
# 注释掉图标相关代码
|
||
# if IconManager.icon_exists(filter_type):
|
||
# item_btn.setIcon(IconManager.get_icon(filter_type, QSize(16, 16)))
|
||
# item_btn.setIconSize(QSize(16, 16))
|
||
# else:
|
||
# # 如果图标不存在,使用原来的文字图标
|
||
# item_btn.setText(f"{icon} {text}")
|
||
|
||
item_btn.setObjectName("navItem")
|
||
item_btn.setCheckable(True)
|
||
item_btn.setFixedSize(QSize(186, 30))
|
||
item_btn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
|
||
|
||
# 设置默认选中
|
||
if filter_type == "overview":
|
||
item_btn.setChecked(True)
|
||
# 发送初始导航信号
|
||
if filter_type in self.nav_mapping:
|
||
section, item_name = self.nav_mapping[filter_type]
|
||
# 使用 QTimer.singleShot 确保在UI完全初始化后发送信号
|
||
QTimer.singleShot(0, lambda: self.navigation_changed.emit(section, item_name, filter_type))
|
||
|
||
# 点击事件
|
||
def on_clicked():
|
||
# 取消其他按钮的选中状态
|
||
for btn in self.findChildren(QPushButton):
|
||
if btn.objectName() == "navItem" and btn != item_btn:
|
||
btn.setChecked(False)
|
||
|
||
item_btn.setChecked(True)
|
||
self.current_filter = filter_type
|
||
self.filter_changed.emit(filter_type)
|
||
|
||
# 发送导航变化信号
|
||
if filter_type in self.nav_mapping:
|
||
section, item_name = self.nav_mapping[filter_type]
|
||
self.navigation_changed.emit(section, item_name, filter_type)
|
||
|
||
item_btn.clicked.connect(on_clicked)
|
||
return item_btn
|
||
|
||
def create_user_info(self, layout):
|
||
"""创建用户信息区域"""
|
||
user_widget = QWidget()
|
||
user_widget.setObjectName("userInfo")
|
||
user_layout = QHBoxLayout(user_widget)
|
||
user_layout.setContentsMargins(20, 15, 20, 20)
|
||
|
||
# 用户头像 - 创建圆形头像
|
||
avatar_label = QLabel("U")
|
||
avatar_label.setObjectName("userAvatar")
|
||
avatar_label.setAlignment(Qt.AlignCenter)
|
||
avatar_label.setFixedSize(32, 32)
|
||
user_layout.addWidget(avatar_label)
|
||
|
||
# 用户名
|
||
username_label = QLabel("Admin")
|
||
username_label.setObjectName("userName")
|
||
user_layout.addWidget(username_label)
|
||
|
||
user_layout.addStretch()
|
||
|
||
# 下拉箭头
|
||
dropdown_label = QLabel("▼")
|
||
dropdown_label.setObjectName("userDropdown")
|
||
user_layout.addWidget(dropdown_label)
|
||
|
||
layout.addWidget(user_widget)
|
||
|
||
def connect_signals(self):
|
||
"""连接信号"""
|
||
pass
|