Drawing LaTeX image in pyside6 using TextObject
01:55 04 Apr 2026

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.

python latex pyside6