From e7ae6a7a1eef8d1ed0c75ec918d6f666c67c0e24 Mon Sep 17 00:00:00 2001 From: Lesacm <1500309685@qq.com> Date: Mon, 17 Nov 2025 11:35:13 +0800 Subject: [PATCH] =?UTF-8?q?UI=E6=9B=B4=E6=94=B910086?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ui/word_style_ui.py | 304 ++++++++++++++++++++++------------------ 1 file changed, 171 insertions(+), 133 deletions(-) diff --git a/src/ui/word_style_ui.py b/src/ui/word_style_ui.py index a29a043..40938a9 100644 --- a/src/ui/word_style_ui.py +++ b/src/ui/word_style_ui.py @@ -73,139 +73,145 @@ class WordRibbon(QFrame): main_layout.addWidget(self.ribbon_area) self.setLayout(main_layout) + def add_separator(self): + """ + 在 Ribbon 主布局里添加一个高度自动适配的竖向分隔线 + """ + line = QFrame() + line.setFrameShape(QFrame.VLine) + line.setFrameShadow(QFrame.Plain) + line.setStyleSheet(""" + QFrame { + background-color: #d0d7de; + width: 1px; + } + """) + line.setFixedWidth(1) + + # Ribbon 区域高度会变,这玩意就自动跟着撑满 + line.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding) + + self.ribbon_layout.addWidget(line) + + + + def create_ribbon_group(self, title, is_special_group=False): + """ + 统一的创建 group 的方法。 + - 如果 is_special_group 为 True:返回单个 group(与原来某些位置的用法一致)。 + - 否则:返回 (group, content_layout) 以便直接往 content_layout 塞控件(与 setup_home_tab 的用法一致)。 + """ + # 对于“特殊组”(天气、每日一言)我们使用 QGroupBox 保持原样 + if is_special_group: + group = QGroupBox(title) + # 应用主题样式 hook + theme_manager.theme_changed.connect(lambda: self._update_group_style(group)) + self._update_group_style(group) + # 给特殊组留一些最小宽度,便于布局(可由调用方调整) + group.setMinimumWidth(100) + return group + + # 常规组:使用 QFrame + 内部 content layout + 底部标题(保留标题在下的视觉) + group = QFrame() + group.setStyleSheet(""" + QFrame { border: none; } + QLabel { font-size: 11px; color: #555; } + """) + + outer_layout = QVBoxLayout(group) + outer_layout.setContentsMargins(3, 3, 3, 3) + outer_layout.setSpacing(2) + + content_widget = QWidget() + content_layout = QHBoxLayout(content_widget) + content_layout.setContentsMargins(0, 0, 0, 0) + content_layout.setSpacing(5) + + title_label = QLabel(title) + title_label.setAlignment(Qt.AlignCenter) + + outer_layout.addWidget(content_widget) + outer_layout.addWidget(title_label) + + group.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) + return group, content_layout + def setup_home_tab(self, layout): - """设置开始标签的功能区内容""" - - # 字体组 - font_group = self.create_ribbon_group("字体") - - # 字体选择 - font_layout = QHBoxLayout() + """设置开始标签 Ribbon —— 保持原有变量/槽名不变,只改布局实现""" + + # ---------- 字体组 ---------- + font_group, font_layout = self.create_ribbon_group("字体") + self.font_combo = QFontComboBox() self.font_combo.setFixedWidth(120) self.font_combo.currentFontChanged.connect(self.on_font_changed) + self.font_size_combo = QComboBox() - self.font_size_combo.addItems(['8', '9', '10', '11', '12', '14', '16', '18', '20', '22', '24', '26', '28', '36', '48', '72']) + self.font_size_combo.addItems( + ['8','9','10','11','12','14','16','18','20','22','24','26','28','36','48','72'] + ) self.font_size_combo.setFixedWidth(70) self.font_size_combo.setCurrentText('12') self.font_size_combo.currentTextChanged.connect(self.on_font_size_changed) - + font_layout.addWidget(self.font_combo) font_layout.addWidget(self.font_size_combo) - - # 字体样式按钮 - font_style_layout = QHBoxLayout() + self.bold_btn = self.create_toggle_button("B", "bold") self.bold_btn.clicked.connect(self.on_bold_clicked) self.italic_btn = self.create_toggle_button("I", "italic") self.italic_btn.clicked.connect(self.on_italic_clicked) self.underline_btn = self.create_toggle_button("U", "underline") self.underline_btn.clicked.connect(self.on_underline_clicked) - - # 字体颜色按钮 self.color_btn = self.create_color_button("A", "color") self.color_btn.clicked.connect(self.on_color_clicked) - - font_style_layout.addWidget(self.bold_btn) - font_style_layout.addWidget(self.italic_btn) - font_style_layout.addWidget(self.underline_btn) - font_style_layout.addWidget(self.color_btn) - - font_main_layout = QVBoxLayout() - font_main_layout.addLayout(font_layout) - font_main_layout.addLayout(font_style_layout) - - font_group.setLayout(font_main_layout) + + font_layout.addWidget(self.bold_btn) + font_layout.addWidget(self.italic_btn) + font_layout.addWidget(self.underline_btn) + font_layout.addWidget(self.color_btn) + font_layout.addStretch() layout.addWidget(font_group) - - # 段落组 - paragraph_group = self.create_ribbon_group("段落") - paragraph_group.setFixedWidth(320) # 增加宽度以适应更宽的按钮 - - # 对齐方式 - align_layout = QHBoxLayout() + self.add_separator() + # ---------- 段落组 ---------- + paragraph_group, paragraph_layout = self.create_ribbon_group("段落") self.align_left_btn = self.create_toggle_button("左对齐", "align_left") self.align_center_btn = self.create_toggle_button("居中", "align_center") self.align_right_btn = self.create_toggle_button("右对齐", "align_right") self.align_justify_btn = self.create_toggle_button("两端对齐", "align_justify") - - align_layout.addWidget(self.align_left_btn) - align_layout.addWidget(self.align_center_btn) - align_layout.addWidget(self.align_right_btn) - align_layout.addWidget(self.align_justify_btn) - - paragraph_layout = QVBoxLayout() - paragraph_layout.addLayout(align_layout) - - paragraph_group.setLayout(paragraph_layout) + + paragraph_layout.addWidget(self.align_left_btn) + paragraph_layout.addWidget(self.align_center_btn) + paragraph_layout.addWidget(self.align_right_btn) + paragraph_layout.addWidget(self.align_justify_btn) + paragraph_layout.addStretch() layout.addWidget(paragraph_group) + self.add_separator() + + # ---------- 样式组(单行水平排列) ---------- + self.init_style_preview_group() + self.add_separator() + - # 样式组 - styles_group = self.create_ribbon_group("样式") - styles_layout = QVBoxLayout() - - # 创建标题样式按钮 - title_buttons_layout = QHBoxLayout() - - # 一级标题按钮 - self.heading1_btn = self.create_style_button("标题1") - self.heading1_btn.clicked.connect(self.on_heading1_clicked) - title_buttons_layout.addWidget(self.heading1_btn) - - # 二级标题按钮 - self.heading2_btn = self.create_style_button("标题2") - self.heading2_btn.clicked.connect(self.on_heading2_clicked) - title_buttons_layout.addWidget(self.heading2_btn) - - # 三级标题按钮 - self.heading3_btn = self.create_style_button("标题3") - self.heading3_btn.clicked.connect(self.on_heading3_clicked) - title_buttons_layout.addWidget(self.heading3_btn) - - styles_layout.addLayout(title_buttons_layout) - - # 第二行样式按钮 - style_buttons_layout = QHBoxLayout() - - # 四级标题按钮 - self.heading4_btn = self.create_style_button("标题4") - self.heading4_btn.clicked.connect(self.on_heading4_clicked) - style_buttons_layout.addWidget(self.heading4_btn) - - # 正文按钮 - self.body_text_btn = self.create_style_button("正文") - self.body_text_btn.clicked.connect(self.on_body_text_clicked) - style_buttons_layout.addWidget(self.body_text_btn) - - style_buttons_layout.addStretch() - styles_layout.addLayout(style_buttons_layout) - - styles_group.setLayout(styles_layout) - layout.addWidget(styles_group) - - # 编辑组 - editing_group = self.create_ribbon_group("编辑") - - # 创建查找替换按钮,使用更适合水平排列的样式 + + # ---------- 编辑组 ---------- + editing_group, editing_layout = self.create_ribbon_group("编辑") self.find_btn = QToolButton() self.find_btn.setText("查找") self.find_btn.setToolButtonStyle(Qt.ToolButtonTextOnly) - self.find_btn.setFixedSize(50, 25) # 设置适合水平排列的尺寸 - + self.find_btn.setFixedSize(55, 25) self.replace_btn = QToolButton() self.replace_btn.setText("替换") self.replace_btn.setToolButtonStyle(Qt.ToolButtonTextOnly) - self.replace_btn.setFixedSize(50, 25) # 设置适合水平排列的尺寸 - - editing_layout = QHBoxLayout() # 改为水平布局 + self.replace_btn.setFixedSize(55, 25) editing_layout.addWidget(self.find_btn) editing_layout.addWidget(self.replace_btn) - editing_layout.addStretch() # 添加弹性空间 - editing_group.setLayout(editing_layout) - editing_group.setFixedWidth(120) # 设置编辑组宽度以适应查找替换按钮 + editing_layout.addStretch() layout.addWidget(editing_group) - + + # 最右侧填充空白,保证整体自适应 layout.addStretch() + def on_font_changed(self, font): """字体变化处理""" @@ -267,6 +273,65 @@ class WordRibbon(QFrame): """两端对齐按钮点击处理""" pass + def init_style_preview_group(self): + """加入 Word 风格的样式预览区域""" + + group = QFrame() + group.setStyleSheet(""" + QFrame { border: none; } + QLabel { font-size: 11px; color: #555; } + """) + + outer_layout = QVBoxLayout(group) + outer_layout.setContentsMargins(3, 3, 3, 3) + outer_layout.setSpacing(2) + + # 上部:样式预览按钮 + preview_widget = QWidget() + preview_layout = QHBoxLayout(preview_widget) + preview_layout.setContentsMargins(0, 0, 0, 0) + preview_layout.setSpacing(8) + + style_items = [ + ("正文", "font-size:14px;"), + ("无间隔", "font-size:14px;"), + ("标题 1", "font-size:22px; font-weight:bold; color:#2E75B6;"), + ("标题 2", "font-size:18px; color:#2E75B6;"), + ("标题 3", "font-size:16px; font-weight:bold;"), + ("副标题", "font-size:14px; font-style:italic; color:#555;"), + ("强调", "font-size:14px; color:#C0504D;"), + ] + + for text, style in style_items: + btn = QPushButton(text) + btn.setFixedSize(95, 60) + btn.setStyleSheet(f""" + QPushButton {{ + background: white; + border: 1px solid #d0d0d0; + border-radius: 3px; + text-align: left; + padding: 5px; + {style} + }} + QPushButton:hover {{ + border: 1px solid #4a90e2; + }} + """) + preview_layout.addWidget(btn) + + preview_layout.addStretch() + + # 下方标题 + title_label = QLabel("样式") + title_label.setAlignment(Qt.AlignCenter) + + outer_layout.addWidget(preview_widget) + outer_layout.addWidget(title_label) + + self.ribbon_layout.addWidget(group) + + def init_theme(self): """初始化主题""" # 连接主题切换信号 @@ -276,31 +341,19 @@ class WordRibbon(QFrame): self.apply_theme() def apply_theme(self): - """应用主题样式""" is_dark = theme_manager.is_dark_theme() - - # 更新功能区背景 colors = theme_manager.get_current_theme_colors() + # 简化仅保留关键样式更新 self.ribbon_area.setStyleSheet(f""" QFrame {{ background-color: {colors['surface']}; border: 1px solid {colors['border']}; border-top: none; }} - QGroupBox {{ - background-color: {colors['surface']}; - color: {colors['text']}; - border: 1px solid {colors['border']}; - }} - QGroupBox::title {{ - color: {colors['text']}; - background-color: transparent; - }} - QLabel {{ - color: {colors['text']}; - background-color: transparent; - }} """) + # 更新下拉框和按钮样式(调用原有 helper) + self.update_combo_styles(is_dark) + self.update_font_button_styles(is_dark) # 更新天气组件样式 if hasattr(self, 'weather_icon_label') and self.weather_icon_label is not None: @@ -330,7 +383,10 @@ class WordRibbon(QFrame): # 更新下拉框样式 self.update_combo_styles(is_dark) - + + def on_theme_changed(self, is_dark): + self.apply_theme() + def update_combo_styles(self, is_dark): """更新下拉框样式""" colors = theme_manager.get_current_theme_colors() @@ -798,24 +854,6 @@ class WordRibbon(QFrame): self.quote_group = None self.quote_visible = False - def create_ribbon_group(self, title, is_special_group=False): - """创建功能区组""" - group = QGroupBox(title) - - # 为非特殊组设置最小宽度以确保标题完整显示 - if not is_special_group: - # 根据标题长度计算合适的最小宽度 - min_width = max(100, len(title) * 12 + 40) # 基础宽度+每个字符约12px - group.setMinimumWidth(min_width) - - # 连接主题切换信号以动态更新样式 - theme_manager.theme_changed.connect(lambda: self._update_group_style(group)) - - # 立即应用当前主题样式 - self._update_group_style(group) - - return group - def _update_group_style(self, group): """更新组样式以适配当前主题""" is_dark = theme_manager.is_dark_theme() -- 2.34.1