Skip to main content

PyQt5 widgets for rendering and editing mathematical formulas

Project description

pyqt5-math-widget

A PyQt5 library for rendering and interactively editing mathematical formulas. No LaTeX engine required — everything is rendered natively via QPainter.


Installation

pip install pyqt5-math-widget

Widgets

Class Purpose
MathView Read-only formula renderer
MathEditor Interactive formula editor with toolbar
MathDialog Modal dialog wrapping MathEditor

MathView — read-only renderer

Basic usage

from pyqt5_math_widget import MathView, FracNode, TextNode, SqrtNode

view = MathView()
view.set_node(FracNode(TextNode("1"), SqrtNode(TextNode("x"))))
layout.addWidget(view)

From a FormulaModel

from pyqt5_math_widget import MathView, FormulaModel

model = FormulaModel()
model.insert_frac()
model.insert_greek("pi")

view = MathView.from_model(model)

API

view.set_node(node)           # Set formula from a FormulaNode
view.set_model(model)         # Attach a FormulaModel
view.set_text("sin(x)")       # Set from plain text
view.set_zoom(1.5)            # Scale factor (default 1.0)
view.zoom()                   # -> float
view.set_background(color)    # QColor fill
view.set_transparent(True)    # Transparent background
view.set_padding(16, 12)      # Horizontal, vertical padding in px
view.set_foreground(color)    # Global text colour
view.to_pixmap(scale=2.0)     # -> QPixmap (for export/saving)
view.to_latex()               # -> str
view.to_sympy()               # -> str
view.to_text()                # -> str
view.model()                  # -> FormulaModel

MathEditor — interactive editor

Basic usage

from pyqt5_math_widget import MathEditor

editor = MathEditor()
editor.formula_changed.connect(lambda s: print("sympy:", s))
editor.latex_changed.connect(lambda s: print("latex:", s))
layout.addWidget(editor)

Constructor parameters

MathEditor(
    parent=None,
    show_toolbar=True,          # Show button toolbar below canvas
    toolbar_groups=None,        # List of group names to show (see below)
    zoom=1.0,                   # Initial zoom level
    readonly=False,             # Disable editing
)

Toolbar groups

Pass a subset of these strings to toolbar_groups:

Group Contents
"struct" fraction, sqrt, power, subscript, integral, sum, product, limit, matrix, ...
"operators" +, -, ·, ×, =, ≠, ≤, ≥, ±, ≈, ∂, ∇, ∈, ∀, →, ...
"greek" α β γ δ ε θ λ μ ν π ρ σ τ φ ψ ω Σ Π Γ Δ Θ Ω ∞ ...
"functions" sin cos tan arcsin log ln exp max min det tr ...
"edit" Delete, Clear, ← →, Undo, Redo
editor.set_toolbar_groups(["struct", "greek", "edit"])

Programmatic insertion API

editor.insert_frac()                   # Fraction a/b
editor.insert_sqrt(nth=False)          # Square root
editor.insert_sqrt(nth=True)           # Nth root
editor.insert_power(wrap_current=True) # Superscript
editor.insert_subscript()              # Subscript
editor.insert_power_sub()              # Combined x^n_m
editor.insert_parens("(", ")")         # Parentheses (any bracket pair)
editor.insert_parens("[", "]")         # Square brackets
editor.insert_abs()                    # |x|
editor.insert_integral(definite=True)  # Definite integral
editor.insert_integral(definite=False) # Indefinite integral
editor.insert_sum(with_limits=True)    # Sum Σ
editor.insert_product(with_limits=True)# Product Π
editor.insert_limit()                  # lim
editor.insert_matrix(2, 2, "(")        # 2x2 matrix with round brackets
editor.insert_matrix(3, 3, "[")        # 3x3 matrix with square brackets
editor.insert_overline()               # Overline
editor.insert_underline()              # Underline
editor.insert_func("sin")             # sin(...) function
editor.insert_greek("alpha")          # α
editor.insert_operator("->")          # →
editor.insert_text("x", italic=True)  # Plain character
editor.insert_node(my_node)           # Raw FormulaNode

Editing control

editor.delete_at_cursor()    # Delete at cursor (Backspace)
editor.clear()               # Clear entire formula
editor.undo()                # Ctrl+Z
editor.redo()                # Ctrl+Y
editor.can_undo()            # -> bool
editor.can_redo()            # -> bool
editor.cursor_left()         # Move cursor left
editor.cursor_right()        # Move cursor right

Output

editor.to_sympy()    # "integrate(sin(x), x)"
editor.to_latex()    # r"\int \sin(x)\,dx"
editor.to_text()     # "integrate(sin(x), x)"
editor.to_pixmap(scale=2.0)   # -> QPixmap

Display control

editor.set_zoom(1.5)
editor.set_readonly(True)
editor.set_toolbar_visible(False)
editor.model()                # -> FormulaModel for direct access
editor.set_model(model)       # Replace model

MathDialog — modal dialog

from pyqt5_math_widget import MathDialog
from PyQt5.QtWidgets import QDialog

dlg = MathDialog(
    parent=self,
    title="Insert Formula",
    initial_text="sin(x)",
    toolbar_groups=["struct", "greek", "edit"],
    show_output=True,
    zoom=1.1,
)
if dlg.exec_() == QDialog.Accepted:
    print(dlg.result_sympy())
    print(dlg.result_latex())
    print(dlg.result_text())

Connect the signal without blocking:

dlg = MathDialog(parent=self)
dlg.accepted_formula.connect(lambda s: print("inserted:", s))
dlg.show()

FormulaModel — programmatic tree manipulation

from pyqt5_math_widget import FormulaModel

model = FormulaModel()
model.insert_frac()
model.insert_text("x")
model.move_right()
model.insert_text("2")

print(model.to_sympy())  # (x) / (2)
print(model.to_latex())  # \frac{x}{2}

model.undo()
model.redo()
model.clear()

Formula node tree

Build a formula tree and display it statically:

from pyqt5_math_widget import (
    MathView, SeqNode, TextNode, FracNode, SqrtNode,
    PowerNode, IntegralNode, SumProdNode, MatrixNode,
    ParenNode, AbsNode,
)

root = SeqNode([
    TextNode("E"),
    TextNode("="),
    FracNode(
        TextNode("m"),
        SqrtNode(SeqNode([TextNode("1"), TextNode("-"), PowerNode(TextNode("v"), TextNode("2"))])),
    ),
])

view = MathView()
view.set_node(root)

Available node types

Class Description
TextNode(text, size, italic, bold, color) Text / symbol
PlaceholderNode(size) Editable placeholder
SeqNode(children) Horizontal sequence
FracNode(num, den) Fraction
SqrtNode(body, index=None) Square / nth root
PowerNode(base, exp) Superscript
SubNode(base, sub) Subscript
PowerSubNode(base, exp, sub) Combined sup+sub
ParenNode(body, left, right) Scalable brackets
AbsNode(body) Absolute value
IntegralNode(body, var, lower, upper) Integral
SumProdNode(kind, body, var, lower, upper) Sum / Product
LimitNode(body, var, approach, direction) Limit
MatrixNode(rows, left, right) Matrix
OverlineNode(body) Overline
UnderlineNode(body) Underline

Each node implements:

node.to_sympy()   # SymPy expression string
node.to_latex()   # LaTeX string
node.to_text()    # Plain text
node.measure(painter)  # -> RenderMetrics
node.draw(painter, x, y, hits, selected, cursor_id)
node.collect_ids()     # -> List[int]
node.clone()           # deep copy

Constants and maps

from pyqt5_math_widget import GREEK_MAP, OPERATOR_MAP

GREEK_MAP["alpha"]   # -> "α"
OPERATOR_MAP["->"]   # -> "→"

Integration

from pyqt5_math_widget import MathDialog
from PyQt5.QtWidgets import QPushButton

btn = QPushButton("\u03A3")
btn.clicked.connect(lambda: self._open_formula_editor())

def _open_formula_editor(self):
    dlg = MathDialog(initial_text=self._input.text(), parent=self.window())
    if dlg.exec_():
        self._input.setText(dlg.result_sympy())

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyqt5_math_widget-1.1.0.tar.gz (32.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyqt5_math_widget-1.1.0-py3-none-any.whl (33.0 kB view details)

Uploaded Python 3

File details

Details for the file pyqt5_math_widget-1.1.0.tar.gz.

File metadata

  • Download URL: pyqt5_math_widget-1.1.0.tar.gz
  • Upload date:
  • Size: 32.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.8.10

File hashes

Hashes for pyqt5_math_widget-1.1.0.tar.gz
Algorithm Hash digest
SHA256 4138250bd7c54900f9c8a5a22c9fba6fa666a7268584bafab51d7fb6eb9c9a15
MD5 232b86134eb7a1addef74f66a58ee8fe
BLAKE2b-256 ec4600c2cd7e8e3e186816a3920548bdc5d0d5fb3d25dbb60cdfb02f3a524add

See more details on using hashes here.

File details

Details for the file pyqt5_math_widget-1.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for pyqt5_math_widget-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3b3e3e57f00dfb3ddbfc09c7b5456995e99689f7d2b8d60a2fe7929b0e79cf7c
MD5 79f8fbdb1c1279968b34067076dc7d0e
BLAKE2b-256 a9ac854cd7ddd146b7b0949b6d26ac1e2fea328e308083367a0354c6228cfbb4

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page