I want to draw rendered LaTeX in a pyside6 application using TextObjectInterface where an object is stored as TextObject and LaTeX is painted on it. I wish to avoid TextImage as it works but there is problem of accumulation of bmp in resource cache when deleting old LaTeX equations and adding new ones. The code below does not generate only text before and after LaTeX image and nothing appears in place of the image. I have a TeX distribution installed. Everything works with TextImage, no error message appears. I am using Python 3.13
import sys
from io import BytesIO
from PySide6.QtWidgets import QApplication, QTextEdit
from PySide6.QtGui import (
QTextObjectInterface,
QTextFormat,
QTextCharFormat,
QImage,
QPainter,
QColor
)
from PySide6.QtCore import QSizeF, QObject, Qt
from matplotlib.figure import Figure
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
LATEX_FORMAT = QTextFormat.UserObject + 1
class LatexRenderer(QObject, QTextObjectInterface):
def __init__(self):
super().__init__()
self._cache = {}
def intrinsicSize(self, doc, posInDocument, format):
latex = format.property(1)
img = self.render_latex(latex)
return QSizeF(img.width(), img.height())
def drawObject(self, painter, rect, doc, posInDocument, format):
latex = format.property(1)
img = self.render_latex(latex)
# DEBUG: Draw a light gray background so we can see the "box"
painter.fillRect(rect, QColor("#f0f0f0"))
painter.drawImage(rect.topLeft(), img)
def render_latex(self, latex):
if latex in self._cache:
return self._cache[latex]
# Force a specific DPI and small figure
fig = Figure(figsize=(1, 1), dpi=100)
canvas = FigureCanvas(fig)
fig.patch.set_alpha(0)
# Using 'mathtext' specifically
fig.text(0.5, 0.5, f"${latex}$",
fontsize=20,
ha='center',
va='center',
color="black")
buf = BytesIO()
# 'tight' is essential, but let's add a small pad to be safe
fig.savefig(buf, format='png', bbox_inches='tight', pad_inches=0.1, transparent=True)
img = QImage()
img.loadFromData(buf.getvalue(), "PNG")
self._cache[latex] = img
return img
class MainWindow(QTextEdit):
def __init__(self):
super().__init__()
# 1. Register handler BEFORE adding text
self.renderer = LatexRenderer()
self.document().documentLayout().registerHandler(LATEX_FORMAT, self.renderer)
# 2. Insert text and math
cursor = self.textCursor()
cursor.insertText("The Pythagorean theorem is: ")
# Use a RAW string for LaTeX
self.insert_latex(cursor, r"a^2 + b^2 = c^2")
cursor.insertText("\n\nAnd the Quadratic formula: ")
self.insert_latex(cursor, r"x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}")
def insert_latex(self, cursor, latex):
fmt = QTextCharFormat()
fmt.setObjectType(LATEX_FORMAT)
fmt.setProperty(1, latex)
cursor.insertText("\uFFFC", fmt)
if __name__ == "__main__":
app = QApplication(sys.argv)
# Removing the deprecated HighDPI line as it's now default
w = MainWindow()
w.resize(600, 400)
w.show()
sys.exit(app.exec())
I want the program to display the formula rendered on the screen, e.g.
a^2 + b^2 = c^2
But nothing appears. I am using QTextObject to draw the LaTeX image directly on an object containing a math expression.