feat(ui): 优化项目导入和创建对话框界面

- 移除了创建项目对话框的最大尺寸限制,提升布局灵活性
- 调整了导入项目对话框中文件列表项的样式和结构
- 更新了图标管理器,新增 import_file_list 图标支持
- 修改了文件列表项组件,使用自定义图标并优化布局间距
- 调整了样式表中多个组件的尺寸和颜色,改善视觉效果
- 优化了文件列表项的显示逻辑,修复了可能的布局问题
- 更新了项目预览图片路径,确保正确显示项目封面
This commit is contained in:
陈横 2025-10-23 18:56:28 +08:00
parent de6446b886
commit fd3eb3e72a
9 changed files with 96 additions and 82 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 335 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

Before

Width:  |  Height:  |  Size: 86 KiB

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

View File

@ -43,7 +43,7 @@ class CreateProjectDialog(QDialog):
self.title_label.setText(self.windowTitle()) self.title_label.setText(self.windowTitle())
self.setModal(True) self.setModal(True)
self.setMinimumSize(1177, 689) # 根据Figma设计调整尺寸 self.setMinimumSize(1177, 689) # 根据Figma设计调整尺寸
self.setMaximumSize(1177, 689) # self.setMaximumSize(1177, 689)
self.resize(1177, 689) # 设置默认尺寸 self.resize(1177, 689) # 设置默认尺寸
# 设置默认项目位置 # 设置默认项目位置
@ -97,13 +97,12 @@ class CreateProjectDialog(QDialog):
title_bar.setCursor(Qt.ArrowCursor) title_bar.setCursor(Qt.ArrowCursor)
return title_bar return title_bar
def create_main_content(self, layout): def create_main_content(self, layout):
"""创建主要内容""" """创建主要内容"""
content_widget = QWidget() content_widget = QWidget()
content_widget.setObjectName("createProjectContent") content_widget.setObjectName("createProjectContent")
content_layout = QHBoxLayout(content_widget) content_layout = QHBoxLayout(content_widget)
content_layout.setContentsMargins(10, 0, 10, 15) # 根据Figma设计调整边距 content_layout.setContentsMargins(10, 0, 10, 15)
content_layout.setSpacing(4) # 添加小间距 content_layout.setSpacing(4) # 添加小间距
# 左侧模板选择区域 # 左侧模板选择区域
@ -140,7 +139,7 @@ class CreateProjectDialog(QDialog):
"""创建模板网格""" """创建模板网格"""
# 滚动区域 # 滚动区域
scroll_area = QScrollArea() scroll_area = QScrollArea()
scroll_area.setFixedSize(724, 595) # scroll_area.setFixedSize(724, 595)
scroll_area.setObjectName("templateScrollArea") scroll_area.setObjectName("templateScrollArea")
scroll_area.setWidgetResizable(True) scroll_area.setWidgetResizable(True)
scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
@ -345,6 +344,9 @@ class CreateProjectDialog(QDialog):
location_group.addLayout(location_layout) location_group.addLayout(location_layout)
form_layout.addLayout(location_group) form_layout.addLayout(location_group)
# form_layout.addStretch()
form_layout.addSpacing(15)
form_layout.addWidget(self.create_button_area()) form_layout.addWidget(self.create_button_area())
layout.addLayout(form_layout) layout.addLayout(form_layout)
@ -354,7 +356,7 @@ class CreateProjectDialog(QDialog):
button_widget = QWidget() button_widget = QWidget()
button_widget.setObjectName("buttonArea") button_widget.setObjectName("buttonArea")
button_layout = QHBoxLayout(button_widget) button_layout = QHBoxLayout(button_widget)
button_layout.setContentsMargins(0, 185, 0, 10) # 根据Figma设计调整边距 button_layout.setContentsMargins(0, 12, 0, 10)
button_layout.setSpacing(10) # 设置按钮间距 button_layout.setSpacing(10) # 设置按钮间距
button_layout.addStretch() button_layout.addStretch()
@ -518,10 +520,6 @@ class CreateProjectDialog(QDialog):
if default_location: if default_location:
self.set_default_location(default_location) self.set_default_location(default_location)
def eventFilter(self, watched, event): def eventFilter(self, watched, event):
"""处理标题栏拖动与按钮交互""" """处理标题栏拖动与按钮交互"""
if watched is self.title_bar: if watched is self.title_bar:
@ -536,7 +534,6 @@ class CreateProjectDialog(QDialog):
return True return True
return super().eventFilter(watched, event) return super().eventFilter(watched, event)
def center_dialog(self): def center_dialog(self):
"""对话框居中""" """对话框居中"""
if self.parent(): if self.parent():

View File

@ -60,6 +60,7 @@ class IconManager:
# 导入对话框 # 导入对话框
'import_file': 'import_file_icon.png', 'import_file': 'import_file_icon.png',
'import_file_list': 'import_file_list_icon.png',
# 创建项目浏览图标 # 创建项目浏览图标
'file_icon': 'file_icon.png', 'file_icon': 'file_icon.png',

View File

@ -66,7 +66,7 @@ class ImportProjectDialog(QDialog):
self._build_ui() self._build_ui()
self._connect_signals() self._connect_signals()
self._show_file_list_placeholder("请拖拽或点击下方按钮选择文件夹") # self._show_file_list_placeholder("请拖拽或点击下方按钮选择文件夹")
self.center_dialog() self.center_dialog()
# 设置圆角遮罩 # 设置圆角遮罩
@ -85,7 +85,7 @@ class ImportProjectDialog(QDialog):
content_widget.setObjectName("importContentArea") content_widget.setObjectName("importContentArea")
content_layout = QVBoxLayout(content_widget) content_layout = QVBoxLayout(content_widget)
content_layout.setContentsMargins(10, 0, 10, 0) content_layout.setContentsMargins(10, 0, 10, 0)
content_layout.setSpacing(21) # content_layout.setSpacing(21)
self._create_import_area(content_layout) self._create_import_area(content_layout)
self._create_options_area(content_layout) self._create_options_area(content_layout)
@ -150,7 +150,7 @@ class ImportProjectDialog(QDialog):
body_frame.setFixedHeight(450) body_frame.setFixedHeight(450)
body_layout = QVBoxLayout(body_frame) body_layout = QVBoxLayout(body_frame)
body_layout.setContentsMargins(15, 10, 15, 10) body_layout.setContentsMargins(15, 10, 15, 10)
body_layout.setSpacing(0) # 使用addSpacing()来精确控制间距 # body_layout.setSpacing(0) # 使用addSpacing()来精确控制间距
self.upload_area = UploadArea() self.upload_area = UploadArea()
body_layout.addWidget(self.upload_area, alignment=Qt.AlignHCenter) body_layout.addWidget(self.upload_area, alignment=Qt.AlignHCenter)
@ -164,13 +164,14 @@ class ImportProjectDialog(QDialog):
hint_label.setWordWrap(True) hint_label.setWordWrap(True)
hint_label.setAlignment(Qt.AlignLeft) hint_label.setAlignment(Qt.AlignLeft)
# 确保label有明确的尺寸避免布局问题 # 确保label有明确的尺寸避免布局问题
hint_label.setMinimumHeight(15) # hint_label.setMinimumHeight(15)
body_layout.addWidget(hint_label, alignment=Qt.AlignLeft) body_layout.addWidget(hint_label, alignment=Qt.AlignLeft)
# 文件列表前的间距 # 文件列表前的间距
body_layout.addSpacing(10) # body_layout.addSpacing(10)
self.file_list = QListWidget() self.file_list = QListWidget()
print("file_list:", self.file_list)
self.file_list.setObjectName("fileList") self.file_list.setObjectName("fileList")
self.file_list.setFrameShape(QFrame.NoFrame) self.file_list.setFrameShape(QFrame.NoFrame)
self.file_list.setSpacing(6) self.file_list.setSpacing(6)
@ -179,6 +180,7 @@ class ImportProjectDialog(QDialog):
self.file_list.setVerticalScrollMode(QListWidget.ScrollPerPixel) self.file_list.setVerticalScrollMode(QListWidget.ScrollPerPixel)
self.file_list.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.file_list.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
self.file_list.setFixedSize(1127, 109) self.file_list.setFixedSize(1127, 109)
# self.file_list.addItem(QListWidgetItem())
body_layout.addWidget(self.file_list, alignment=Qt.AlignCenter) body_layout.addWidget(self.file_list, alignment=Qt.AlignCenter)
section_layout.addWidget(body_frame) section_layout.addWidget(body_frame)
@ -245,9 +247,11 @@ class ImportProjectDialog(QDialog):
# ----------------------------------------------------------------- Helpers -- # ----------------------------------------------------------------- Helpers --
def _show_file_list_placeholder(self, message: str) -> None: def _show_file_list_placeholder(self, message: str) -> None:
if not self.file_list: if self.file_list is None:
print("file_list is None")
return return
self.file_list.clear() self.file_list.clear()
print(message)
placeholder = QListWidgetItem(message) placeholder = QListWidgetItem(message)
placeholder.setFlags(Qt.NoItemFlags) placeholder.setFlags(Qt.NoItemFlags)
placeholder.setTextAlignment(Qt.AlignCenter) placeholder.setTextAlignment(Qt.AlignCenter)
@ -256,12 +260,12 @@ class ImportProjectDialog(QDialog):
self.import_btn.setEnabled(False) self.import_btn.setEnabled(False)
def _populate_file_list(self) -> None: def _populate_file_list(self) -> None:
if not self.file_list: if self.file_list is None:
return return
self.file_list.clear() self.file_list.clear()
if not self.selected_folders: if not self.selected_folders:
self._show_file_list_placeholder("请拖拽或点击下方按钮选择文件夹") # self._show_file_list_placeholder("请拖拽或点击下方按钮选择文件夹")
return return
for folder_path in self.selected_folders: for folder_path in self.selected_folders:
@ -273,29 +277,11 @@ class ImportProjectDialog(QDialog):
folder_name, folder_path, file_count, size_str folder_name, folder_path, file_count, size_str
) )
# --- 这是修改后的逻辑 ---
# 1. 创建一个空的 QListWidgetItem
item = QListWidgetItem() item = QListWidgetItem()
# 2. 将它添加到列表中
self.file_list.addItem(item) self.file_list.addItem(item)
# 3. 将自定义小部件设置给它
# 注意:完全不需要调用 setSizeHint()
self.file_list.setItemWidget(item, item_widget) self.file_list.setItemWidget(item, item_widget)
# --- 修改结束 --- item.setSizeHint(QSize(1095, 36))
# item = QListWidgetItem()
# self.file_list.addItem(item)
# self.file_list.setItemWidget(item, item_widget)
# 触发布局以获得正确的 sizeHint
item_widget.layout().activate()
hint = item_widget.sizeHint()
if not hint.isValid() or hint.height() == 0:
hint = item_widget.minimumSizeHint()
if hint.isValid():
item.setSizeHint(hint)
# 移除调试输出 # 移除调试输出
@ -308,41 +294,47 @@ class ImportProjectDialog(QDialog):
) -> QWidget: ) -> QWidget:
container = QWidget() container = QWidget()
container.setObjectName("fileListItem") container.setObjectName("fileListItem")
# container.setFixedSize(1115, 24)
# --- 新增代码 ---
# 强制为列表项的容器设置一个最小高度。
# 这是最可靠的方法,可以防止它因尺寸计算问题而变得不可见。
# 60px 是一个比较合理的值可以根据您的UI风格调整。
container.setMinimumHeight(60)
# --- 新增代码结束 ---
layout = QHBoxLayout(container) layout = QHBoxLayout(container)
layout.setContentsMargins(16, 10, 16, 10) layout.setContentsMargins(6, 0, 6, 0)
layout.setSpacing(12)
icon_label = QLabel() icon_label = QLabel()
icon_label.setObjectName("fileListItemIcon") icon_label.setObjectName("fileListItemIcon")
icon = QApplication.style().standardIcon(QStyle.SP_DriveHDIcon) # icon = QApplication.style().standardIcon(QStyle.SP_DriveHDIcon)
icon_label.setPixmap(icon.pixmap(24, 24)) if IconManager.icon_exists("import_file_list"):
layout.addWidget(icon_label, alignment=Qt.AlignCenter) icon = IconManager.get_icon("import_file_list", QSize(18, 18))
else:
icon = QApplication.style().standardIcon(QStyle.SP_DriveHDIcon)
icon_label.setPixmap(icon.pixmap(18, 18))
icon_label.setFixedSize(18, 18)
layout.addWidget(icon_label, alignment=Qt.AlignVCenter)
text_block = QWidget() layout.setSpacing(10)
text_layout = QVBoxLayout(text_block)
text_layout.setContentsMargins(0, 0, 0, 0)
text_layout.setSpacing(4)
title_label = QLabel(folder_name) title_label = QLabel(folder_name)
title_label.setObjectName("fileListItemTitle") title_label.setObjectName("fileListItemTitle")
title_label.setWordWrap(False) title_label.setWordWrap(False)
text_layout.addWidget(title_label) title_label.setAlignment(Qt.AlignVCenter | Qt.AlignLeft)
title_label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
# title_label.setFixedHeight(24)
layout.addWidget(title_label)
meta_label = QLabel(f"{folder_path} · {file_count} 个文件 · {size_str}") # path_label = QLabel(folder_path)
meta_label.setObjectName("fileListItemMeta") # path_label.setObjectName("fileListItemMeta")
meta_label.setWordWrap(False) # path_label.setWordWrap(False)
meta_label.setToolTip(folder_path) # path_label.setAlignment(Qt.AlignVCenter | Qt.AlignLeft)
text_layout.addWidget(meta_label) # path_label.setToolTip(folder_path)
# path_label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
# path_label.setFixedHeight(24)
# layout.addWidget(path_label, 1)
layout.addWidget(text_block, 1) # stats_label = QLabel(f"{file_count} files / {size_str}")
# stats_label.setObjectName("fileListItemMeta")
# stats_label.setWordWrap(False)
# stats_label.setAlignment(Qt.AlignVCenter | Qt.AlignRight)
# stats_label.setFixedHeight(24)
# layout.addWidget(stats_label)
return container return container
@ -609,11 +601,6 @@ class UploadArea(QWidget):
select_btn.setCursor(Qt.PointingHandCursor) select_btn.setCursor(Qt.PointingHandCursor)
select_btn.clicked.connect(self.select_files_requested.emit) select_btn.clicked.connect(self.select_files_requested.emit)
select_btn.setFixedSize(151, 42) select_btn.setFixedSize(151, 42)
button_font = select_btn.font()
button_font.setFamily("Inter")
button_font.setPointSize(16)
button_font.setWeight(QFont.Normal)
select_btn.setFont(button_font)
content_layout.addWidget(select_btn, alignment=Qt.AlignCenter) content_layout.addWidget(select_btn, alignment=Qt.AlignCenter)
content_layout.addSpacing(10) content_layout.addSpacing(10)

View File

@ -569,7 +569,8 @@ class StyleSheet:
} }
#createProjectContent{ #createProjectContent{
background-color: #0c0c0d; background-color: #0c0c0d;
border-radius: 5px;
} }
#templateSection { #templateSection {
@ -1048,8 +1049,8 @@ class StyleSheet:
font-family: "Inter" "Microsoft YaHei", "Segoe UI", sans-serif; font-family: "Inter" "Microsoft YaHei", "Segoe UI", sans-serif;
font-size: 14px; font-size: 14px;
font-weight: 500; font-weight: 500;
min-width: 24px; min-width: 18px;
min-height: 24px; min-height: 18px;
} }
QDialog#CreateProjectDialog #customCloseBtn:hover { QDialog#CreateProjectDialog #customCloseBtn:hover {
@ -1090,8 +1091,8 @@ class StyleSheet:
font-family: "Inter" "Microsoft YaHei", "Segoe UI", sans-serif; font-family: "Inter" "Microsoft YaHei", "Segoe UI", sans-serif;
font-size: 14px; font-size: 14px;
font-weight: 500; font-weight: 500;
min-width: 24px; min-width: 18px;
min-height: 24px; min-height: 18px;
} }
QDialog#ImportProjectDialog #customCloseBtn:hover { QDialog#ImportProjectDialog #customCloseBtn:hover {
@ -1235,21 +1236,27 @@ class StyleSheet:
border-color: rgba(76, 104, 196, 0.6); border-color: rgba(76, 104, 196, 0.6);
} }
QDialog#ImportProjectDialog #fileList QWidget#fileListItem { QDialog#ImportProjectDialog #fileList QWidget#fileListItem {
background-color: rgba(62, 68, 84, 0.3); background-color: transparent;
border: 1px solid rgba(74, 80, 96, 0.45); border: none;
border-radius: 6px; border-radius: 0;
} }
QDialog#ImportProjectDialog #fileList QWidget#fileListItem:hover { QDialog#ImportProjectDialog #fileList QWidget#fileListItem:hover {
background-color: rgba(76, 104, 164, 0.28); background-color: transparent;
border-color: rgba(63, 104, 196, 0.6); border: none;
}
QDialog#ImportProjectDialog #fileList QLabel#fileListItemIcon {
background: transparent;
} }
QDialog#ImportProjectDialog QLabel#fileListItemTitle { QDialog#ImportProjectDialog QLabel#fileListItemTitle {
background-color: transparent;
color: #f3f4f8; color: #f3f4f8;
font-family: "Inter" "Microsoft YaHei", "Segoe UI", sans-serif; font-family: "Inter" "Microsoft YaHei", "Segoe UI", sans-serif;
font-size: 14px; font-size: 12x;
font-weight: 500; font-weight: 500;
letter-spacing: 0.3px; letter-spacing: 0.3px;
} }
@ -1308,7 +1315,7 @@ class StyleSheet:
background-color: #0c0c0d; background-color: #0c0c0d;
border-top: 1px solid rgba(58, 63, 76, 0.7); border-top: 1px solid rgba(58, 63, 76, 0.7);
margin: 0 10px; /* 上下0px左右20px */ margin: 0 10px; /* 上下0px左右20px */
min-height: 64px; min-height: 36px;
border-bottom-left-radius: 5px; border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px; border-bottom-right-radius: 5px;
} }

View File

@ -1,13 +1,35 @@
[ [
{
"id": 6,
"title": "、",
"date": "2025-10-23 18:43:38",
"type": "empty",
"image": "C:\\Users\\29381\\Desktop\\、\\、.png",
"path": "C:\\Users\\29381\\Desktop",
"project_dir": "C:\\Users\\29381\\Desktop\\、",
"description": "",
"status": "normal"
},
{
"id": 5,
"title": "~",
"date": "2025-10-23 18:42:41",
"type": "empty",
"image": "C:\\Users\\29381\\Desktop\\~\\~.png",
"path": "C:\\Users\\29381\\Desktop",
"project_dir": "C:\\Users\\29381\\Desktop\\~",
"description": "asd",
"status": "normal"
},
{ {
"id": 4, "id": 4,
"title": "aasd", "title": "aasd",
"date": "2025-10-17 16:49:10", "date": "2025-10-20 10:22:53",
"type": "empty", "type": "imported",
"image": "C:\\Users\\29381\\Desktop\\aasd\\aasd.png", "image": "C:\\Users\\29381\\Desktop\\aasd\\aasd.png",
"path": "C:\\Users\\29381\\Desktop", "path": "C:\\Users\\29381\\Desktop",
"project_dir": "C:\\Users\\29381\\Desktop\\aasd", "project_dir": "C:\\Users\\29381\\Desktop\\aasd",
"description": "asd", "description": "从文件夹 aasd 导入",
"status": "normal" "status": "normal"
}, },
{ {
@ -15,7 +37,7 @@
"title": "a", "title": "a",
"date": "2025-10-17 16:48:59", "date": "2025-10-17 16:48:59",
"type": "imported", "type": "imported",
"image": "C:\\Users\\29381\\Desktop\\a\\a.png", "image": "C:\\Users\\29381\\Desktop\\MetaCore-startup\\MetaCore\\Resources\\ProjectPreviews\\preview_3_1760927381193.png",
"path": "C:\\Users\\29381\\Desktop", "path": "C:\\Users\\29381\\Desktop",
"project_dir": "C:\\Users\\29381\\Desktop\\a", "project_dir": "C:\\Users\\29381\\Desktop\\a",
"description": "从文件夹 a 导入", "description": "从文件夹 a 导入",
@ -37,7 +59,7 @@
"title": "XNWX", "title": "XNWX",
"date": "2025-10-14 18:05:51", "date": "2025-10-14 18:05:51",
"type": "imported", "type": "imported",
"image": "C:\\Users\\29381\\Desktop\\MetaCore-startup\\MetaCore\\Resources\\ProjectPreviews\\preview_1_1760628516144.png", "image": "C:\\Users\\29381\\Desktop\\MetaCore-startup\\MetaCore\\Resources\\ProjectPreviews\\preview_1_1760694205849.png",
"path": "C:\\Users\\29381\\Desktop", "path": "C:\\Users\\29381\\Desktop",
"project_dir": "C:\\Users\\29381\\Desktop\\XNWX", "project_dir": "C:\\Users\\29381\\Desktop\\XNWX",
"description": "从文件夹 XNWX 导入", "description": "从文件夹 XNWX 导入",