Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. Drawing LaTeX image in pyside6 using TextObject
Qt 6.11 is out! See what's new in the release blog

Drawing LaTeX image in pyside6 using TextObject

Scheduled Pinned Locked Moved Unsolved Qt for Python
3 Posts 2 Posters 123 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • P Offline
    P Offline
    pasmon90
    wrote last edited by
    #1

    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 API 
    
    

    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())

    JonBJ 2 Replies Last reply
    0
    • P pasmon90

      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 API 
      
      

      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())

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote last edited by
      #2

      @pasmon90
      For my part at least: especially when using Python, please use the forum's "Code" tags ( </> button or blocks delimited at start and end by ``` ) to properly format your post and your code, including leading whitespace.

      1 Reply Last reply
      0
      • P pasmon90

        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 API 
        
        

        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())

        JonBJ Offline
        JonBJ Offline
        JonB
        wrote last edited by
        #3

        @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?

        1 Reply Last reply
        0

        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved