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

409 lines
15 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
项目设置页面组件
这个页面允许用户配置项目相关的设置,包括:
- 默认项目创建位置
- 项目模板设置
- 项目命名规则
- 其他项目相关配置
"""
import os
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
class ProjectSettingsPage(QWidget):
"""
项目设置页面
提供项目相关的配置选项,主要包括默认项目位置的设置。
"""
# 信号定义
settings_changed = pyqtSignal() # 设置发生变化时发出
def __init__(self):
super().__init__()
self.settings = QSettings("MetaCore", "ProjectManager") # 用于保存设置
self.init_ui()
self.load_settings()
def init_ui(self):
"""初始化用户界面"""
self.setObjectName("settingsPage")
self.setAttribute(Qt.WA_StyledBackground, True)
self.main_layout = QVBoxLayout(self)
self.main_layout.setContentsMargins(0, 30, 24, 30)
self.main_layout.setSpacing(0)
self.content_container = QFrame()
self.content_container.setObjectName("settingsContentArea")
self.content_container.setFrameShape(QFrame.NoFrame)
self.content_container.setAttribute(Qt.WA_StyledBackground, True)
self.main_layout.addWidget(self.content_container)
self.content_layout = QVBoxLayout(self.content_container)
self.content_layout.setContentsMargins(0, 0, 0, 0)
self.content_layout.setSpacing(0)
header_widget = self.create_page_header()
self.content_layout.addWidget(header_widget)
body_widget = self.create_settings_body()
self.content_layout.addWidget(body_widget)
self.content_layout.addStretch()
def create_page_header(self):
"""创建面包屑与标题区域"""
header_widget = QWidget()
header_widget.setObjectName("contentHeader")
header_layout = QVBoxLayout(header_widget)
header_layout.setContentsMargins(36, 32, 36, 24)
header_layout.setSpacing(0)
breadcrumb_widget = QWidget()
breadcrumb_widget.setObjectName("breadcrumbContainer")
breadcrumb_layout = QHBoxLayout(breadcrumb_widget)
breadcrumb_layout.setContentsMargins(0, 0, 0, 0)
breadcrumb_layout.setSpacing(8)
breadcrumb_base = QLabel("设置中心")
breadcrumb_base.setObjectName("breadcrumbBase")
breadcrumb_layout.addWidget(breadcrumb_base)
breadcrumb_separator = QLabel("/")
breadcrumb_separator.setObjectName("breadcrumbSeparator")
breadcrumb_layout.addWidget(breadcrumb_separator)
breadcrumb_current = QLabel("项目设置")
breadcrumb_current.setObjectName("breadcrumbCurrent")
breadcrumb_layout.addWidget(breadcrumb_current)
breadcrumb_layout.addStretch()
header_layout.addWidget(breadcrumb_widget)
# title_label = QLabel("项目设置")
# title_label.setObjectName("settingsTitle")
# header_layout.addWidget(title_label)
# subtitle_label = QLabel("配置项目创建和管理的相关设置。")
# subtitle_label.setObjectName("settingsSubtitle")
# subtitle_label.setWordWrap(True)
# header_layout.addWidget(subtitle_label)
return header_widget
def create_settings_body(self):
"""创建设置内容区域,结构与项目区域组件保持一致"""
scroll_area = QScrollArea()
scroll_area.setObjectName("projectScrollArea")
scroll_area.setFrameShape(QFrame.NoFrame)
scroll_area.setWidgetResizable(True)
scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
body_container = QWidget()
body_container.setObjectName("settingsBody")
body_layout = QVBoxLayout(body_container)
# body_layout.setContentsMargins(36, 24, 6, 18)
body_layout.setSpacing(24)
settings_card = self.create_settings_card()
body_layout.addWidget(settings_card)
body_layout.addStretch()
scroll_area.setWidget(body_container)
return scroll_area
def create_settings_card(self):
"""创建主体设置卡片内容"""
card = QFrame()
card.setObjectName("settingsCard")
card.setFrameShape(QFrame.NoFrame)
card.setAttribute(Qt.WA_StyledBackground, True)
card_layout = QVBoxLayout(card)
card_layout.setContentsMargins(0, 0, 0, 0)
card_layout.setSpacing(0)
sections = [
{
"title": "默认项目位置",
"description": "设置新项目的默认创建位置。",
"placeholder": "选择默认项目创建位置...",
"browse": self.browse_default_location,
"reset": self.reset_default_location,
"attr": "path_input",
},
{
"title": "打开设置",
"description": "设置新项目的默认打开位置。",
"placeholder": "选择默认项目打开位置...",
"browse": self.browse_open_location,
"reset": self.reset_open_location,
"attr": "open_path_input",
},
]
total = len(sections)
for index, section_info in enumerate(sections):
is_first = index == 0
is_last = index == total - 1
section_widget = self.create_path_section(
title=section_info["title"],
description=section_info["description"],
placeholder=section_info["placeholder"],
browse_handler=section_info["browse"],
reset_handler=section_info["reset"],
input_attr=section_info["attr"],
is_first=is_first,
is_last=is_last,
)
card_layout.addWidget(section_widget)
return card
def create_path_section(
self,
title,
description,
placeholder,
browse_handler,
reset_handler,
input_attr,
is_first=False,
is_last=False,
):
"""创建路径类型设置行"""
section = QFrame()
section.setObjectName("settingsRow")
section.setFrameShape(QFrame.NoFrame)
section.setAttribute(Qt.WA_StyledBackground, True)
section.setProperty("isFirstRow", "true" if is_first else "false")
section.setProperty("isLastRow", "true" if is_last else "false")
section.style().unpolish(section)
section.style().polish(section)
section_layout = QVBoxLayout(section)
bottom_margin = 24 if is_last else 0
section_layout.setContentsMargins(32, 24, 32, bottom_margin)
section_layout.setSpacing(0)
title_label = QLabel(title)
title_label.setObjectName("settingsSectionTitle")
section_layout.addWidget(title_label)
section_layout.addSpacing(8)
desc_label = QLabel(description)
desc_label.setObjectName("settingsSectionDesc")
desc_label.setWordWrap(True)
section_layout.addWidget(desc_label)
section_layout.addSpacing(15)
field_row = QWidget()
field_row.setObjectName("settingsFieldRow")
field_layout = QHBoxLayout(field_row)
field_layout.setContentsMargins(19, 0, 0, 0)
field_layout.setSpacing(12)
path_input = QLineEdit()
path_input.setObjectName("settingsPathInput")
path_input.setPlaceholderText(placeholder)
path_input.setReadOnly(True)
path_input.setFixedHeight(48)
# path_input.setMinimumWidth(1099)
field_layout.addWidget(path_input, stretch=1)
browse_btn = QPushButton("浏览...")
browse_btn.setObjectName("settingsPrimaryBtn")
browse_btn.setCursor(Qt.PointingHandCursor)
browse_btn.setFixedSize(175, 48)
browse_btn.clicked.connect(browse_handler)
field_layout.addWidget(browse_btn)
reset_btn = QPushButton("重置")
reset_btn.setObjectName("settingsGhostBtn")
reset_btn.setCursor(Qt.PointingHandCursor)
reset_btn.setFixedSize(175, 48)
reset_btn.clicked.connect(reset_handler)
field_layout.addWidget(reset_btn)
section_layout.addWidget(field_row)
setattr(self, input_attr, path_input)
return section
def browse_open_location(self):
"""浏览选择打开位置"""
current_path = self.open_path_input.text() or self.get_default_projects_path()
folder = QFileDialog.getExistingDirectory(
self,
"选择默认项目打开位置",
current_path
)
if folder:
self.open_path_input.setText(folder)
# 可以根据需要添加保存逻辑
self.save_settings_immediately("default_open_location", self.open_path_input.text())
def reset_open_location(self):
"""重置为默认打开位置"""
default_path = self.get_default_projects_path()
self.open_path_input.setText(default_path)
self.save_settings_immediately("default_open_location", self.open_path_input.text())
def create_project_creation_section(self, layout):
"""创建项目创建设置区域"""
# 分组框
group_box = QGroupBox("项目创建设置")
group_box.setObjectName("settingsGroup")
group_layout = QVBoxLayout(group_box)
group_layout.setSpacing(15)
# 自动打开项目文件夹选项
self.auto_open_checkbox = QCheckBox("创建项目后自动打开项目文件夹")
self.auto_open_checkbox.setObjectName("settingsCheckbox")
group_layout.addWidget(self.auto_open_checkbox)
# 创建README文件选项
self.create_readme_checkbox = QCheckBox("自动创建 README.md 文件")
self.create_readme_checkbox.setObjectName("settingsCheckbox")
self.create_readme_checkbox.setChecked(True) # 默认选中
group_layout.addWidget(self.create_readme_checkbox)
# 创建.gitignore文件选项
self.create_gitignore_checkbox = QCheckBox("自动创建 .gitignore 文件")
self.create_gitignore_checkbox.setObjectName("settingsCheckbox")
group_layout.addWidget(self.create_gitignore_checkbox)
layout.addWidget(group_box)
def create_button_section(self, layout):
"""创建按钮区域(已移除,路径选择后自动保存)"""
# 不再需要按钮区域,路径选择后自动保存
pass
def get_default_projects_path(self):
"""获取默认项目目录路径"""
# 获取当前文件所在目录的上级目录(项目根目录)
# current_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# return os.path.join(current_dir, "MetaCore_Projects")
current_dir = ''
return current_dir
def browse_default_location(self):
"""浏览选择默认位置"""
current_path = self.path_input.text() or self.get_default_projects_path()
folder = QFileDialog.getExistingDirectory(
self,
"选择默认项目创建位置",
current_path
)
if folder:
self.path_input.setText(folder)
# 路径选择后立即保存设置
self.save_settings_immediately("default_project_location", self.path_input.text())
def reset_default_location(self):
"""重置为默认位置"""
default_path = self.get_default_projects_path()
self.path_input.setText(default_path)
self.save_settings_immediately("default_project_location", self.path_input.text())
def load_settings(self):
"""加载保存的设置"""
# 加载默认项目位置
default_path = self.settings.value(
"default_project_location",
self.get_default_projects_path()
)
self.path_input.setText(default_path)
default_open_path = self.settings.value(
"default_open_location",
self.get_default_projects_path()
)
self.open_path_input.setText(default_open_path)
# 加载其他设置
# self.auto_open_checkbox.setChecked(
# self.settings.value("auto_open_folder", False, type=bool)
# )
# self.create_readme_checkbox.setChecked(
# self.settings.value("create_readme", True, type=bool)
# )
# self.create_gitignore_checkbox.setChecked(
# self.settings.value("create_gitignore", False, type=bool)
# )
def save_settings_immediately(self, key, value):
"""立即保存设置(路径选择后自动调用)"""
# 保存默认项目位置
self.settings.setValue(key, value)
# 确保设置被保存
self.settings.sync()
# 发出设置变化信号
self.settings_changed.emit()
# 显示简短的成功提示(可选)
# QMessageBox.information(self, "设置已保存", "默认项目位置已更新!")
# def apply_settings(self):
# """应用设置(保留方法以防其他地方调用)"""
# self.save_settings_immediately()
#
# # 显示成功消息
# QMessageBox.information(self, "设置已保存", "项目设置已成功保存!")
#
# def restore_defaults(self):
# """恢复默认设置(已移除按钮,保留方法以防其他地方调用)"""
# reply = QMessageBox.question(
# self,
# "恢复默认设置",
# "确定要恢复所有设置为默认值吗?",
# QMessageBox.Yes | QMessageBox.No,
# QMessageBox.No
# )
#
# if reply == QMessageBox.Yes:
# # 恢复默认值
# self.path_input.setText(self.get_default_projects_path())
#
# # 立即保存恢复的设置
# self.save_settings_immediately()
#
# QMessageBox.information(self, "恢复完成", "已恢复默认设置!")
def get_default_project_location(self):
"""获取默认项目位置"""
return self.settings.value(
"default_project_location",
self.get_default_projects_path()
)
def get_default_open_location(self):
"""获取默认项目位置"""
return self.settings.value(
"default_open_location",
self.get_default_projects_path()
)
# def get_project_creation_settings(self):
# """获取项目创建设置"""
# return {
# 'auto_open_folder': self.settings.value("auto_open_folder", False, type=bool),
# 'create_readme': self.settings.value("create_readme", True, type=bool),
# 'create_gitignore': self.settings.value("create_gitignore", False, type=bool),
# }