Skip to content

Commit adfc395

Browse files
committed
feat(gui): 重构UI布局并全面刷新界面样式
本次提交对图形用户界面(GUI)进行了一次重大的视觉和结构性更新,旨在提升整体的用户体验和现代化观感。 主要变更: 1. 主窗口布局重构: * 将主窗口的 QSplitter 布局从垂直(上下)更改为水平(左右),将核心功能区(标签页)置于左侧,日志输出区置于右侧。 * 此布局更符合桌面应用的常规使用习惯,提高了空间利用率。 2. 全局样式表 (QSS) 刷新: * 全面重写 gui/style.qss,建立了一套更统一、更美观的视觉规范。 * 引入了 #0078d4 作为主强调色,并应用于按钮、分组框标题、焦点边框和进度条,增强了视觉一致性。 * 重新设计了 QTabWidget 的样式,使其外观更简洁、现代。 * 统一了 QPushButton, QLineEdit, QComboBox 等常用控件的内边距、边框和圆角,使整体观感更和谐。 3. UX 微调: * 为品牌合并的 QMessageBox 对话框增加了最小宽度,以防止在显示较长品牌名时出现文字截断的问题。 4. 文档同步: * 更新了 gui/GEMINI.md 文档,以准确反映新的 QSplitter 布局结构。
1 parent 1f2a116 commit adfc395

File tree

3 files changed

+66
-29
lines changed

3 files changed

+66
-29
lines changed

gui/GEMINI.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
## 1. 设计理念
66

77
- **组件化**: 界面被拆分为多个独立的组件(Widgets),每个组件负责一块特定的功能区域。
8-
- **主从结构**: `main_window.py` 是主窗口,它负责整合所有子组件,并管理应用的整体布局和生命周期。其核心布局现在基于 `QTabWidget`,将不同的功能区(如“批处理工具”和“映射编辑器”)分隔到独立的标签页中,使界面更加清晰
8+
- **主从结构**: `main_window.py` 是主窗口,它负责整合所有子组件,并管理应用的整体布局和生命周期。其核心布局基于 `QSplitter` 实现左右分割:左侧是包含“批处理工具”和“映射编辑器”等功能区的 `QTabWidget`,右侧是日志输出区域
99
- **现代化主题**: 界面通过 `qdarkstyle` 库实现了现代化的暗色主题,并在此基础上通过 `gui/style.qss` 文件进行了微调和定制,以优化视觉效果和用户体验。
1010
- **响应式布局**: 在需要排列多个按钮或元素的场景(如 `BatchToolsWidget`),采用了自定义的 `FlowLayout`,使得元素可以根据窗口大小自动换行,提高了界面的适应性。
1111
- **对话框驱动**: 所有需要用户输入的交互都通过弹出的对话框(`dialogs.py`)来完成。
@@ -46,7 +46,7 @@
4646

4747
- **`main_window.py` (`MainWindow`)**:
4848
- **作用**: GUI 应用的入口和主容器。
49-
- **核心职责**: 初始化并管理 Worker 线程;包含所有 `handle_*` 槽函数,作为后台请求的UI响应中心;使用 `QTabWidget` 构建主界面布局
49+
- **核心职责**: 初始化并管理 Worker 线程;包含所有 `handle_*` 槽函数,作为后台请求的UI响应中心;使用 `QSplitter``QTabWidget` 构建主界面的左右布局
5050

5151
- **`dialogs.py`**:
5252
- **作用**: 包含了应用中所有自定义的 `QDialog` 对话框。

gui/main_window.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,14 @@ def __init__(self):
4949
self.keyword_input.setPlaceholderText("输入游戏名/关键词...")
5050
self.manual_mode_checkbox = QCheckBox("手动模式")
5151
self.search_button = QPushButton("🔍 开始搜索")
52-
self.search_button.setStyleSheet("background-color: #007BFF; color: white; padding: 5px;")
5352
top_layout.addWidget(QLabel("游戏名:"))
5453
top_layout.addWidget(self.keyword_input, 1)
5554
top_layout.addWidget(self.manual_mode_checkbox)
5655
top_layout.addWidget(self.search_button)
5756
main_layout.addLayout(top_layout)
5857

5958
# Main splitter for controls and log
60-
main_splitter = QSplitter(Qt.Vertical)
59+
main_splitter = QSplitter(Qt.Horizontal)
6160

6261
# --- New Tab-based layout for controls ---
6362
self.tab_widget = QTabWidget()
@@ -79,8 +78,8 @@ def __init__(self):
7978
main_splitter.addWidget(self.tab_widget) # Add tab widget instead of the old controls widget
8079
main_splitter.addWidget(log_widget)
8180

82-
# Adjust splitter ratio to give more space to the log initially (60% top, 40% bottom)
83-
main_splitter.setSizes([int(self.height() * 0.6), int(self.height() * 0.4)])
81+
# Adjust splitter ratio for an initial 50/50 split
82+
main_splitter.setSizes([int(self.width() * 0.5), int(self.width() * 0.5)])
8483
main_layout.addWidget(main_splitter)
8584

8685
# Setup logging
@@ -239,6 +238,8 @@ def handle_brand_merge_requested(self, new_brand_name, suggested_brand):
239238
msg_box.setWindowTitle("品牌查重")
240239
msg_box.setText(f"新品牌 '<b>{new_brand_name}</b>' 与已存在的品牌 '<b>{suggested_brand}</b>' 高度相似。")
241240
msg_box.setInformativeText("您希望如何处理?")
241+
# Set a minimum width to prevent text truncation
242+
msg_box.setStyleSheet("QMessageBox { min-width: 600px; }")
242243
merge_button = msg_box.addButton("合并为 ‘" + suggested_brand + "’ (推荐)", QMessageBox.AcceptRole)
243244
create_button = msg_box.addButton("创建新品牌 ‘" + new_brand_name + "’", QMessageBox.ActionRole)
244245
msg_box.addButton("取消操作", QMessageBox.RejectRole)

gui/style.qss

Lines changed: 59 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,81 @@
1-
/* Otaku-Sync Custom Stylesheet */
1+
/* Otaku-Sync Custom Stylesheet v2 */
22

33
/* --- General --- */
44
QWidget {
5-
/* A cleaner, modern font stack for cross-platform compatibility. Segoe UI is preferred on Windows. */
65
font-family: "Segoe UI", "Helvetica Neue", "Arial", sans-serif;
7-
font-size: 14px;
6+
font-size: 15px;
7+
/* A slightly lighter base text color for better overall contrast */
8+
color: #E0E0E0;
89
}
910

10-
/* --- Widgets --- */
11-
QPushButton, QLineEdit, QComboBox {
12-
padding: 8px;
13-
border-radius: 5px; /* Slightly rounded corners for a modern feel */
11+
/* --- Key Widgets --- */
12+
QPushButton, QLineEdit, QComboBox, QPlainTextEdit, QTextEdit {
13+
/* Unified padding and border-radius */
14+
padding: 9px;
15+
border-radius: 5px;
16+
/* A slightly lighter background to distinguish from the window */
17+
background-color: #333;
18+
border: 1px solid #444;
19+
}
20+
21+
/* Provide visual feedback on focus */
22+
QLineEdit:focus, QPlainTextEdit:focus, QTextEdit:focus, QComboBox:focus {
23+
border: 1px solid #0078d4; /* Use accent color for focus */
1424
}
1525

1626
QPushButton {
1727
font-weight: bold;
28+
color: #fff;
29+
background-color: #0078d4; /* Main accent color for primary actions */
1830
}
1931

20-
QTextEdit {
21-
border: 1px solid #444; /* A subtle border to define the log area */
22-
border-radius: 5px;
23-
padding: 5px;
32+
QPushButton:hover {
33+
background-color: #008dfa; /* Lighter blue on hover */
2434
}
2535

26-
/* --- Layout Sections (QGroupBox) --- */
36+
/* --- Tab Widget --- */
37+
QTabWidget::pane {
38+
/* The area where tab content is shown */
39+
border-top: 2px solid #444;
40+
margin-top: -2px; /* Align with the tab bar bottom border */
41+
}
42+
43+
QTabBar::tab {
44+
/* Style for individual tabs */
45+
padding: 10px 20px;
46+
background-color: transparent;
47+
color: #aaa; /* Dim unselected tabs */
48+
border: none; /* Remove default borders */
49+
font-weight: bold;
50+
}
51+
52+
QTabBar::tab:hover {
53+
color: #fff; /* Highlight on hover */
54+
}
55+
56+
QTabBar::tab:selected {
57+
/* Style for the active tab */
58+
color: #fff;
59+
background-color: #444; /* Lighter background for the tab itself */
60+
border-bottom: 2px solid #0078d4; /* Accent color line */
61+
}
62+
63+
64+
/* --- GroupBox --- */
2765
QGroupBox {
28-
/* Adds breathing room around the entire section */
2966
margin-top: 12px;
30-
border: 1px solid #555; /* A subtle border to frame the section */
67+
border: 1px solid #444; /* Match other borders */
3168
border-radius: 8px;
32-
padding-top: 25px; /* Pushes content down to make space for the title */
69+
padding-top: 25px;
3370
}
3471

3572
QGroupBox::title {
36-
/* Positions the title inside the top border */
3773
subcontrol-origin: margin;
3874
subcontrol-position: top left;
39-
40-
/* Style for the title itself */
41-
padding: 4px 10px;
75+
padding: 4px 12px;
4276
margin-left: 10px;
43-
background-color: #666; /* A distinct but harmonious background for the title */
44-
color: #eee;
77+
background-color: #0078d4; /* Use accent color for titles */
78+
color: #fff;
4579
border-radius: 5px;
4680
font-weight: bold;
4781
}
@@ -52,9 +86,11 @@ QProgressBar {
5286
border-radius: 5px;
5387
text-align: center;
5488
font-weight: bold;
89+
background-color: #333;
90+
border: 1px solid #444;
5591
}
5692

5793
QProgressBar::chunk {
58-
background-color: #0078d4; /* A pleasant blue for progress */
94+
background-color: #0078d4;
5995
border-radius: 3px;
60-
}
96+
}

0 commit comments

Comments
 (0)