ARTICLE AD BOX
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^2But nothing appears. I am using QTextObject to draw the LaTeX image directly on an object containing a math expression.
