如何在PyQt6中实现类似Word的公式输入单元格模块?
在PyQt6中实现公式输入单元格模块
核心思路
这类公式输入模块本质是组合多个输入控件模拟公式结构,再通过拼接控件内容生成目标格式的字符串。下面以分式结构为例,逐步实现可复用的公式单元格,并支持获取格式化公式值。
1. 自定义分式公式单元格
先实现最基础的分式输入组件,用QWidget作为容器,包含分子输入框、分数线、分母输入框:
from PyQt6.QtWidgets import (QWidget, QLineEdit, QVBoxLayout, QLabel) from PyQt6.QtCore import Qt class FractionFormulaCell(QWidget): def __init__(self, parent=None): super().__init__(parent) layout = QVBoxLayout(self) layout.setSpacing(2) layout.setContentsMargins(5, 5, 5, 5) # 分子输入框 self.numerator_input = QLineEdit() self.numerator_input.setPlaceholderText("分子") self.numerator_input.setAlignment(Qt.AlignmentFlag.AlignCenter) self.numerator_input.setStyleSheet("border: 1px solid #ccc; border-radius: 3px;") # 分数线 divider = QLabel("————") divider.setAlignment(Qt.AlignmentFlag.AlignCenter) # 分母输入框 self.denominator_input = QLineEdit() self.denominator_input.setPlaceholderText("分母") self.denominator_input.setAlignment(Qt.AlignmentFlag.AlignCenter) self.denominator_input.setStyleSheet("border: 1px solid #ccc; border-radius: 3px;") layout.addWidget(self.numerator_input) layout.addWidget(divider) layout.addWidget(self.denominator_input) # 获取格式化后的公式字符串 def get_formula_string(self): numerator = self.numerator_input.text().strip() or "" denominator = self.denominator_input.text().strip() or "" return f"{{({numerator})/({denominator})}}"
2. 集成到主窗口并扩展功能
如果需要支持多种公式类型(比如上下标、根号),可以用QStackedLayout切换不同的公式模板,搭配工具栏按钮让用户选择:
from PyQt6.QtWidgets import (QMainWindow, QToolBar, QAction, QStackedLayout, QHBoxLayout) class FormulaEditorWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("公式输入器") self.resize(400, 300) # 创建工具栏 toolbar = QToolBar() self.addToolBar(toolbar) # 分式切换按钮 frac_action = QAction("分式", self) frac_action.triggered.connect(self.switch_to_fraction) toolbar.addAction(frac_action) # 上下标切换按钮 sub_sup_action = QAction("上下标", self) sub_sup_action.triggered.connect(self.switch_to_subsup) toolbar.addAction(sub_sup_action) # 获取公式按钮 get_formula_action = QAction("获取公式", self) get_formula_action.triggered.connect(self.print_current_formula) toolbar.addAction(get_formula_action) # 堆叠布局切换不同公式组件 self.stacked_layout = QStackedLayout() # 添加分式组件 self.frac_cell = FractionFormulaCell() self.stacked_layout.addWidget(self.frac_cell) # 添加上下标组件 self.subsup_cell = self._create_subsup_cell() self.stacked_layout.addWidget(self.subsup_cell) central_widget = QWidget() central_widget.setLayout(self.stacked_layout) self.setCentralWidget(central_widget) # 创建上下标公式单元格 def _create_subsup_cell(self): widget = QWidget() layout = QVBoxLayout(widget) layout.setSpacing(5) # 底数输入框 self.base_input = QLineEdit() self.base_input.setPlaceholderText("底数") self.base_input.setAlignment(Qt.AlignmentFlag.AlignCenter) self.base_input.setStyleSheet("border: 1px solid #ccc; border-radius: 3px;") # 上下标输入框容器 subsup_layout = QHBoxLayout() subsup_layout.setSpacing(10) self.sub_input = QLineEdit() self.sub_input.setPlaceholderText("下标") self.sub_input.setMaximumWidth(80) self.sub_input.setAlignment(Qt.AlignmentFlag.AlignCenter) self.sub_input.setStyleSheet("border: 1px solid #ccc; border-radius: 3px;") self.sup_input = QLineEdit() self.sup_input.setPlaceholderText("上标") self.sup_input.setMaximumWidth(80) self.sup_input.setAlignment(Qt.AlignmentFlag.AlignCenter) self.sup_input.setStyleSheet("border: 1px solid #ccc; border-radius: 3px;") subsup_layout.addWidget(self.sub_input) subsup_layout.addWidget(self.sup_input) subsup_layout.setAlignment(Qt.AlignmentFlag.AlignCenter) layout.addWidget(self.base_input) layout.addLayout(supsup_layout) return widget # 切换到分式组件 def switch_to_fraction(self): self.stacked_layout.setCurrentWidget(self.frac_cell) # 切换到上下标组件 def switch_to_subsup(self): self.stacked_layout.setCurrentWidget(self.subsup_cell) # 获取并打印当前公式 def print_current_formula(self): current_widget = self.stacked_layout.currentWidget() if current_widget == self.frac_cell: print(self.frac_cell.get_formula_string()) elif current_widget == self.subsup_cell: base = self.base_input.text().strip() or "" sub = self.sub_input.text().strip() or "" sup = self.sup_input.text().strip() or "" formula = base if sub: formula += f"_{{{sub}}}" if sup: formula += f"^{{{sup}}}" print(f"{{{formula}}}") # 运行测试 if __name__ == "__main__": from PyQt6.QtWidgets import QApplication import sys app = QApplication(sys.argv) window = FormulaEditorWindow() window.show() sys.exit(app.exec())
3. 关键说明
- 样式自定义:可以通过
setStyleSheet调整输入框、容器的外观,模拟Word公式编辑器的视觉效果; - 扩展公式类型:如果需要支持根号、积分等结构,只需新增对应的自定义单元格类,添加到堆叠布局即可;
- 公式格式扩展:根据需求修改
get_formula_string方法,生成符合要求的格式字符串(比如LaTeX格式、自定义格式)。
内容的提问来源于stack exchange,提问作者dynamic.aerospace.inc
相关产品推荐
相关产品推荐

