Drawing LaTeX image in pyside6 using TextObject
-
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. It did not work in 3.13 nor in 3.12.13.
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. I need python equal or greater than .12 for gemini api feature So i cannot use pyqt6 as it does not get install. Recommend me the best version of python for QTextObject and gemini APIimport 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, Qtfrom matplotlib.figure import Figure
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvasLATEX_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 imgclass 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 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. It did not work in 3.13 nor in 3.12.13.
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. I need python equal or greater than .12 for gemini api feature So i cannot use pyqt6 as it does not get install. Recommend me the best version of python for QTextObject and gemini APIimport 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, Qtfrom matplotlib.figure import Figure
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvasLATEX_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 imgclass 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 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. It did not work in 3.13 nor in 3.12.13.
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. I need python equal or greater than .12 for gemini api feature So i cannot use pyqt6 as it does not get install. Recommend me the best version of python for QTextObject and gemini APIimport 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, Qtfrom matplotlib.figure import Figure
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvasLATEX_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 imgclass 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())@pasmon90 said in Drawing LaTeX image in pyside6 using TextObject:
I need python equal or greater than .12 for gemini api feature So i cannot use pyqt6 as it does not get install.
I know nothing about your situation. But if you are saying that PyQt6 would work, or is at least worth trying to compare against PySide behaviour, have you tried running PyQt6 with whatever 3.12/3.13 version of Python, regardless of whether PyQt6 is supplied with an older version of Python?