How to indent paragraph in QtextEdit

Viewed 97

Everything works in another program, where only textedit, and in the main program - does not work. Apparently the reason is in some kind of Layout. Can you tell me what could be? I am attaching an excerpt from the code.))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))

from PyQt5 import QtCore, QtGui, QtWidgets
import os
from PyQt5.QtWidgets import QTextEdit, QApplication
from PyQt5.QtGui import QTextDocument, QTextCursor, QTextBlockFormat
class TextEditor(QTextEdit):

 def __init__(self,parent):
    super().__init__(parent)
    self.initUI()

 def initUI(self):

    cursor = QTextCursor(self.document())
    cursor.select(QTextCursor.Document)
    fmt = QTextBlockFormat()
    fmt.setTextIndent(60)
    cursor.mergeBlockFormat(fmt)
    font= QtGui.QFont()
    font.setFamily("Times New Roman")
    font.setPointSize(14)
    self.setFont(font)
          
    self.show()

 def insertFromMimeData(self, md):
  
        cursor = self.textCursor()
        fmt = QTextBlockFormat()
        fmt.setTextIndent(cursor.blockFormat().textIndent())
        cursor.mergeBlockFormat(fmt)
        cursor.insertText(md.text())

class Ui_mainWindow(object):
 def setupUi(self, mainWindow):
    mainWindow.setObjectName("mainWindow")
    mainWindow.resize(800, 600)
    self.centralwidget = QtWidgets.QWidget(mainWindow)
    self.centralwidget.setObjectName("centralwidget")
    self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
    self.gridLayout.setObjectName("gridLayout")
    self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
    self.horizontalLayout_2.setObjectName("horizontalLayout_2")
    self.textEdit = TextEditor(self.centralwidget)
    self.textEdit.setObjectName("textEdit")
    self.horizontalLayout_2.addWidget(self.textEdit)
    self.gridLayout.addLayout(self.horizontalLayout_2, 2, 0, 1, 1)
    self.horizontalLayout = QtWidgets.QHBoxLayout()
    self.horizontalLayout.setObjectName("horizontalLayout")
    self.pushButton = QtWidgets.QPushButton(self.centralwidget)
    font = QtGui.QFont()
    font.setFamily("Times New Roman")
    font.setPointSize(10)
    font.setBold(True)
    font.setWeight(75)
    self.pushButton.setFont(font)
    self.pushButton.setObjectName("pushButton")
    self.horizontalLayout.addWidget(self.pushButton)
    self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
    font = QtGui.QFont()
    font.setFamily("Times New Roman")
    font.setPointSize(10)
    font.setBold(True)
    font.setWeight(75)
    self.pushButton_2.setFont(font)
    self.pushButton_2.setObjectName("pushButton_2")
    self.horizontalLayout.addWidget(self.pushButton_2)
    self.gridLayout.addLayout(self.horizontalLayout, 0, 0, 1, 1)
    self.label = QtWidgets.QLabel(self.centralwidget)
    font = QtGui.QFont()
    font.setPointSize(11)
    self.label.setFont(font)
    self.label.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
    self.label.setObjectName("label")
    self.gridLayout.addWidget(self.label, 1, 0, 1, 1)
    mainWindow.setCentralWidget(self.centralwidget)
    self.menubar = QtWidgets.QMenuBar(mainWindow)
    self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
    self.menubar.setObjectName("menubar")
    mainWindow.setMenuBar(self.menubar)
    self.statusbar = QtWidgets.QStatusBar(mainWindow)
    self.statusbar.setObjectName("statusbar")
    mainWindow.setStatusBar(self.statusbar)
    self.pig()
    self.retranslateUi(mainWindow)
    QtCore.QMetaObject.connectSlotsByName(mainWindow)
    self.butclick()
    self.butclick2()
 
1 Answers

Use QTextBlockFormat.setTextIndent and QTextCursor.mergeBlockFormat instead of QTextEdit.setStyleSheet:

    cursor = QTextCursor(self.textEdit.document())
    cursor.select(QTextCursor.Document)
    fmt = QTextBlockFormat()
    fmt.setTextIndent(60)
    cursor.mergeBlockFormat(fmt)

Result:

QTextEdit with indented text

UPD As @ВалерияГригорьева rightfully pointed out, the indent is discarded when pasting plain text (although I would expect it should be taken from the current block by the default implementation). Therefore we need to override QTextEdit.insertFromMimeData and apply indentation on insert:

cursor = self.textCursor()
fmt = QTextBlockFormat()
fmt.setTextIndent(cursor.blockFormat().textIndent())
cursor.mergeBlockFormat(fmt)
cursor.insertText(md.text())

For pasting the rich text, on the other hand, we don't want to suppress indents because they are a part of the rich text formatting and thus we can rely on the default implementation of QTextEdit.insertFromMimeData.

Complete code sample (for PyQt5):

import sys
from PyQt5.QtWidgets import QTextEdit, QApplication
from PyQt5.QtGui import QTextDocument, QTextCursor, QTextBlockFormat


class TextEditor(QTextEdit):

    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        # format text edit
        self.setPlainText(
                "Impedit voluptatem sequi quae quo quos. \n" + 
                "Asperiores non repellat culpa nihil. \n" + 
                "Voluptatum ut numquam dolorem molestiae voluptatem " + 
                "est modi necessitatibus. \n" + 
                "Hic rerum voluptas voluptatem. \n" + 
                "Ut expedita unde eum molestias voluptatem aut" + 
                "dignissimos dolor. \n" + 
                "Non illo dolore ut doloremque ut.")
        cursor = QTextCursor(self.document())
        cursor.select(QTextCursor.Document)
        fmt = QTextBlockFormat()
        fmt.setTextIndent(60)
        cursor.mergeBlockFormat(fmt)
        # setup UI
        self.setGeometry(300, 300, 300, 200)
        self.setWindowTitle('Text indent')
        self.show()

    def insertFromMimeData(self, md):
        # leave processing of the rich text as it is
        if md.hasFormat("application/x-qrichtext") or md.hasHtml():
            super().insertFromMimeData(md)
        else:
            # force indentation from the current block 
            # (shouldn't Qt do this by default, huh?)
            cursor = self.textCursor()
            fmt = QTextBlockFormat()
            fmt.setTextIndent(cursor.blockFormat().textIndent())
            cursor.mergeBlockFormat(fmt)
            cursor.insertText(md.text())


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = TextEditor()
    sys.exit(app.exec())
Related