Search code examples
pyqt5markdownqtextedit

Setting tab width in QTextEdit when displaying Markdown?


I'm making a markdown editor/viewer using QTextEdit and while testing it, I noticed that when I'm making a list, it automatically adds an indentation to the start of the bullet (picture here). Then when I'm adding sub lists, it adds some large gaps which I can only think of as a whole tab width.

I Tried:

  1. Reading the docs, but it seems like they didn't discuss about this
  2. recovering the text inside the QTextEdit editor and it looks just fine without the indentations at the start of the bullet, which makes me think that it is an issue related in the setMarkdown method. Text inside the QTextEdit editor:
    - bullet 1
       - sub bullet 1
    - bullet 2
       - sub bullet 2
  1. I forgot to mention that, I've already read about How to change the width of tabs in a QPlainTextEdit, which suggests that I should use setTabStopDistance(). You can see at the code which I used to reproduce the issue below that I've already tried this but it only worked at the QTextEdit editor and not in the markdown viewer. I have provided the before and after of using setTabStopDistance()

Question:

  1. What causes the indentation at the start of the bullets?
  2. Is it possible it remove the indentation at the start of the bullets?
  3. Is it possible to make the gap of the sub bullets smaller?

Code I used to reproduce the issue:

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *

class SidebarTextEdit(QTextEdit):
    def __init__(self):
        super().__init__()
        self.setTabStopDistance(QFontMetricsF(self.font()).horizontalAdvance(' ') * 4)

class SidebarWindow(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        # -- main layout -- #
        self.main_layout = QVBoxLayout()
        self.setLayout(self.main_layout)

        # -- text edit -- #
        self.markdown_editor = SidebarTextEdit()
        self.markdown_editor.textChanged.connect(self.reload_markdown)

        self.markdown_viewer = SidebarTextEdit()
        self.markdown_viewer.setReadOnly(True)

        self.main_layout.addWidget(self.markdown_editor)
        self.main_layout.addWidget(self.markdown_viewer)

    def reload_markdown(self):
        markdown_text = self.markdown_editor.toPlainText()
        # print(markdown_text)
        self.markdown_viewer.setMarkdown(markdown_text)

if __name__ == "__main__":
    app = QApplication(sys.argv)

    w = SidebarWindow()
    w.show()

    sys.exit(app.exec_())

Solution

  • The list indentation is set on the document() of the text edit, and can be changed with setIndentWidth():

    class SidebarTextEdit(QTextEdit):
        def __init__(self):
            super().__init__()
            indent = QFontMetricsF(self.font()).horizontalAdvance('    ')
            self.document().setIndentWidth(indent)