MetaCore-startup/MetaCore/ui/main_window.py
2025-10-17 16:56:28 +08:00

316 lines
12 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
主窗口类
"""
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from ui.sidebar import Sidebar
from ui.project_area import ProjectArea
from ui.create_project_dialog import CreateProjectDialog
from ui.import_project_dialog import ImportProjectDialog
from ui.project_settings_page import ProjectSettingsPage
from data.project_manager import ProjectManager
from ui.icon_manager import IconManager
from ui.widget import UniversalMessageDialog
class MainWindow(QMainWindow):
"""主窗口类"""
def __init__(self, project_manager: ProjectManager):
super().__init__()
self.project_manager = project_manager
self.current_filter = "overview"
self.current_search = ""
self.init_ui()
self.connect_signals()
# 设置窗口属性 - 匹配 Figma 设计规范
self.setWindowTitle("MetaCore - 项目管理平台")
self.setWindowIcon(IconManager.get_icon('app'))
self.setMinimumSize(1200, 800) # 增加最小尺寸,确保良好的用户体验
self.resize(1440, 960) # 调整默认尺寸,匹配现代显示器比例
# 响应式布局标志
self.is_compact_mode = False
# 居中显示
self.center_window()
def init_ui(self):
"""初始化UI"""
# 创建中央部件
central_widget = QWidget()
self.setCentralWidget(central_widget)
# 创建主布局
main_layout = QHBoxLayout(central_widget)
# 设置部件内容周围的边距大小分别为左、上、右和下。
# 边距由布局系统使用,并且子类可能使用边距来指定绘制区域(例如,不包括框架)。
# 更改页边距会触发一个 resizeEvent() 事件。
main_layout.setContentsMargins(0, 0, 0, 0)
main_layout.setSpacing(0)
# 创建侧边栏
self.sidebar = Sidebar(self.project_manager)
main_layout.addWidget(self.sidebar)
# 创建项目区域
self.project_area = ProjectArea(self.project_manager)
# 创建项目设置页面
self.project_settings_page = ProjectSettingsPage()
# 创建堆叠窗口部件来管理不同页面
self.stacked_widget = QStackedWidget()
self.stacked_widget.addWidget(self.project_area) # 索引 0: 项目区域
self.stacked_widget.addWidget(self.project_settings_page) # 索引 1: 项目设置页面
main_layout.addWidget(self.stacked_widget)
# 设置布局比例
main_layout.setStretch(0, 0) # 侧边栏固定宽度
main_layout.setStretch(1, 1) # 堆叠窗口部件自适应
# 创建状态栏
# self.create_status_bar()
# 创建菜单栏
# self.create_menu_bar()
def create_status_bar(self):
"""创建状态栏"""
self.status_bar = self.statusBar()
# 项目数量标签
self.project_count_label = QLabel()
self.status_bar.addWidget(self.project_count_label)
# 分隔符
self.status_bar.addPermanentWidget(QLabel("|"))
# 当前用户标签
user_label = QLabel("当前用户: Admin")
self.status_bar.addPermanentWidget(user_label)
# 更新项目数量
self.update_project_count()
def create_menu_bar(self):
"""创建菜单栏"""
menubar = self.menuBar()
# 文件菜单
file_menu = menubar.addMenu('文件(&F)')
# 新建项目
new_action = QAction('新建项目(&N)', self)
new_action.setShortcut('Ctrl+N')
new_action.setStatusTip('创建新项目')
new_action.triggered.connect(self.show_create_project_dialog)
file_menu.addAction(new_action)
# 导入项目
import_action = QAction('导入项目(&I)', self)
import_action.setShortcut('Ctrl+I')
import_action.setStatusTip('导入现有项目')
import_action.triggered.connect(self.show_import_project_dialog)
file_menu.addAction(import_action)
file_menu.addSeparator()
# 退出
exit_action = QAction('退出(&X)', self)
exit_action.setShortcut('Ctrl+Q')
exit_action.setStatusTip('退出应用程序')
exit_action.triggered.connect(self.close)
file_menu.addAction(exit_action)
# 编辑菜单
edit_menu = menubar.addMenu('编辑(&E)')
# 搜索
search_action = QAction('搜索项目(&S)', self)
search_action.setShortcut('Ctrl+F')
search_action.setStatusTip('搜索项目')
search_action.triggered.connect(self.focus_search)
edit_menu.addAction(search_action)
# 视图菜单
view_menu = menubar.addMenu('视图(&V)')
# 网格视图
grid_action = QAction('网格视图(&G)', self)
grid_action.setCheckable(True)
grid_action.setChecked(True)
grid_action.triggered.connect(lambda: self.project_area.set_view_mode('grid'))
view_menu.addAction(grid_action)
# 列表视图
list_action = QAction('列表视图(&L)', self)
list_action.setCheckable(True)
list_action.triggered.connect(lambda: self.project_area.set_view_mode('list'))
view_menu.addAction(list_action)
# 创建视图模式组
view_group = QActionGroup(self)
view_group.addAction(grid_action)
view_group.addAction(list_action)
# 帮助菜单
help_menu = menubar.addMenu('帮助(&H)')
# 关于
about_action = QAction('关于(&A)', self)
about_action.triggered.connect(self.show_about)
help_menu.addAction(about_action)
def connect_signals(self):
"""连接信号"""
# 侧边栏信号
self.sidebar.filter_changed.connect(self.on_filter_changed)
self.sidebar.navigation_changed.connect(self.on_navigation_changed) # 新增导航变化信号
self.sidebar.create_project_requested.connect(self.show_create_project_dialog)
self.sidebar.import_project_requested.connect(self.show_import_project_dialog)
# 项目区域信号
self.project_area.search_changed.connect(self.on_search_changed)
self.project_area.create_project_requested.connect(self.show_create_project_dialog)
self.project_area.import_project_requested.connect(self.show_import_project_dialog)
# 项目设置页面信号
self.project_settings_page.settings_changed.connect(self.on_project_settings_changed)
# 项目管理器信号
self.project_manager.projects_changed.connect(self.update_project_count)
self.project_manager.projects_changed.connect(self.refresh_projects)
def center_window(self):
"""窗口居中"""
screen = QApplication.desktop().screenGeometry()
size = self.geometry()
self.move(
(screen.width() - size.width()) // 2,
(screen.height() - size.height()) // 2
)
def resizeEvent(self, event):
"""窗口大小变化事件"""
super().resizeEvent(event)
# 检查是否需要切换到紧凑模式 - 匹配 Figma 响应式断点
width = event.size().width()
should_be_compact = width < 1400 # 调整断点,匹配现代设计标准
if should_be_compact != self.is_compact_mode:
self.is_compact_mode = should_be_compact
self.update_layout_mode()
def update_layout_mode(self):
"""更新布局模式 - 匹配 Figma 响应式设计"""
if self.is_compact_mode:
# 紧凑模式:缩小侧边栏,匹配小屏幕设计
self.sidebar.setFixedWidth(260)
else:
# 正常模式:标准侧边栏宽度,匹配 Figma 设计
self.sidebar.setFixedWidth(300)
def on_filter_changed(self, filter_type: str):
"""过滤器改变"""
self.current_filter = filter_type
self.refresh_projects()
def on_navigation_changed(self, section: str, item_name: str, filter_type: str):
"""导航变化处理"""
# 根据filter_type决定显示哪个页面
if filter_type == "project_settings":
# 切换到项目设置页面
self.stacked_widget.setCurrentIndex(1)
else:
# 切换到项目区域
self.stacked_widget.setCurrentIndex(0)
# 更新项目区域的面包屑导航和标题
self.project_area.update_navigation(section, item_name)
def on_search_changed(self, search_text: str):
"""搜索改变"""
self.current_search = search_text
self.refresh_projects()
def on_project_settings_changed(self):
"""项目设置变化处理"""
# 设置已更改,可以在这里处理相关逻辑
# 例如:更新创建项目对话框的默认位置
print("项目设置已更新")
def refresh_projects(self):
"""刷新项目显示"""
if self.current_search:
projects = self.project_manager.search_projects(self.current_search)
else:
projects = self.project_manager.get_projects_by_type(self.current_filter)
self.project_area.update_projects(projects)
def update_project_count(self):
"""更新项目数量"""
count = len(self.project_manager.get_all_projects())
# 如果状态栏存在,更新项目数量显示
if hasattr(self, 'project_count_label'):
self.project_count_label.setText(f"项目总数: {count}")
# 可以在这里添加其他更新逻辑,比如更新窗口标题
self.setWindowTitle(f"MetaCore - 项目管理平台 ({count} 个项目)")
def show_create_project_dialog(self):
"""显示创建项目对话框"""
dialog = CreateProjectDialog(self.project_manager, self.project_settings_page, self)
if dialog.exec_() == QDialog.Accepted:
self.refresh_projects()
def show_import_project_dialog(self):
"""显示导入项目对话框"""
dialog = ImportProjectDialog(self.project_manager, self.project_settings_page, self)
if dialog.exec_() == QDialog.Accepted:
self.refresh_projects()
def focus_search(self):
"""聚焦搜索框"""
self.project_area.focus_search()
def show_about(self):
"""显示关于对话框"""
# QMessageBox.about(self, "关于 MetaCore",
# "MetaCore 项目管理平台\n\n"
# "版本: 1.0.0\n"
# "基于 PyQt5 开发\n\n"
# "© 2024 MetaCore Team")
UniversalMessageDialog.show_info(self,
"关于 MetaCore",
"MetaCore 项目管理平台\n\n"
"版本: 1.0.0\n"
"基于 PyQt5 开发\n\n"
"© 2024 MetaCore Team",
False, "确定")
def closeEvent(self, event):
"""关闭事件"""
# reply = QMessageBox.question(self, '确认退出',
# '确定要退出 MetaCore 吗?',
# QMessageBox.Yes | QMessageBox.No,
# QMessageBox.No)
reply = UniversalMessageDialog.show_info(self,
'确认退出',
'确定要退出 MetaCore 吗?',
True, "", "")
if reply == QDialog.Accepted:
# 保存数据
self.project_manager.save_projects()
event.accept()
else:
event.ignore()