Search code examples
pythonpyqt5pyside2qtexteditqtextdocument

Why is formatting carrying over between separate QTextDocuments and how can I prevent it?


I'm currently working on a WYSIWYG text editor using a QTextEdit. Each time a new file is loaded, I reset and reformat the QTextDocument, read the file (which is blank), then .setHtml() its contents to the editor. I intended for each newly created file to always have the same default style defined in a single function.

Instead, new text entered into the empty file is receiving formatting from the previously loaded QTextDocument rather than defaulting to formatting I've provided. It's most obvious if I copy-paste syntax highlighted code into one document, then create and type into a new document. The font, font color, and background color will all carry over to the new document despite not existing in its html structure.


This is the function I'm currently running before any file is loaded into the QTextEdit:

fontDefault = QFont()
fontDefault.setFamily("Yantramanav")
fontDefault.setPointSize(11)
fontDefault.setWeight(QFont.Normal)

# editor is a QTextEdit.
def reset_document(editor, defaultFont=fontDefault):
    newDocument = QTextDocument()
    newDocument.setDocumentMargin(12)
    newDocument.setDefaultFont(defaultFont)

    editor.setDocument(newDocument)
    editor.setCurrentFont(defaultFont)

    # Stored on the QTextEdit yet is reset when replacing the QTextDocument.
    editor.setTabStopWidth(33)

I had assumed any old formatting would be lost when the document, which stores the formatting, is replaced. Why is this not the case and how can I ensure that only my default styles are being applied?


Solution

  • The QTextCursor is carrying the previous charFormat between documents. Even though the QTextDocument which it points to is replaced, the cursor itself persists and is assigned to the new document. This process evidently does not cause the cursor to sample a charFormat from its current position, as happens each time the cursor is moved, so it still carries the charFormat from its last position in the previous document.

    Preventing this overlap is as simple as replacing or moving the cursor, both of which result in a cursor which takes its charFormat from the new document. Add one of the following to the reset_document() function:

    # 1. Remove old formatting by replacing the cursor.
    newCursor = QTextCursor(newDocument)
    editor.setTextCursor(newCursor)
    
    # 2. Remove old formatting by moving the cursor.
    oldCursor = editor.textCursor()
    oldCursor.movePosition(QTextCursor.Start, QTextCursor.MoveAnchor)
    editor.setTextCursor(oldCursor)