Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

How to use QTextBlockFormat with QTextEdit?



  • I'm certain there's something simple I'm not doing, but I can't seem to use any of the rich text editing features QTextBlockFormat implements. Below is a minimal code example.

    import sys
    
    from PySide6.QtWidgets import QApplication, QTextEdit
    
    
    if __name__ == "__main__":
        app = QApplication([])
        text_edit = QTextEdit()
        text_edit.document().firstBlock().blockFormat().setTextIndent(40.0)   # example of rich text parameter I want to set
        text_edit.show()
        sys.exit(app.exec())
    
    

    For whatever reason, whenever I call setTextIndent() or any other formatting property, the value doesn't "stick." In the debugging console, I get perplexing behavior like below

    >>> text_edit.document().firstBlock().blockFormat().setLeftMargin(50.0)
    >>> text_edit.document().firstBlock().blockFormat().leftMargin()
    0.0
    

    Why doesn't calling setLeftMargin() change the leftMargin property for the QTextEdit's first QTextBlock? Surely, I'm not understanding something?

    I even did a sanity check to make sure each successive method call returned the class type I expected

    >>> text_edit.document()
    <PySide6.QtGui.QTextDocument(0x2d319b0) at 0x7f7589f4f680>
    >>> text_edit.document().firstBlock()
    <PySide6.QtGui.QTextBlock object at 0x7f7589f4f740>
    >>> text_edit.document().firstBlock().blockFormat()
    <PySide6.QtGui.QTextBlockFormat(QTextFormat::FormatType(1)) at 0x7f7589f4f700>
    

    Please help and thanks in advance!



  • @duyjuwumu
    Python hides from you the fact that the C++ QTextBlock QTextDocument::firstBlock() & QTextBlockFormat QTextBlock::blockFormat() methods are const, meaning that you cannot use them to change anything in firstBlock().blockFormat(), hence you see the value unchanged.

    I don't have an example --- perhaps you can find one --- but I believe you need to copy the existing block/block format, make your change in the copy, and then reset the block format to your newly altered one.



  • @duyjuwumu
    Python hides from you the fact that the C++ QTextBlock QTextDocument::firstBlock() & QTextBlockFormat QTextBlock::blockFormat() methods are const, meaning that you cannot use them to change anything in firstBlock().blockFormat(), hence you see the value unchanged.

    I don't have an example --- perhaps you can find one --- but I believe you need to copy the existing block/block format, make your change in the copy, and then reset the block format to your newly altered one.


  • Lifetime Qt Champion

    Hi,

    As @JonB suggested, you need to take a copy of the object, modify it and then set it again. The same applies for example on the font used for a widget.



  • @JonB That did the trick

    After reading the Rich-text processing docs, I really should be using a QTextCursor. Here's a minimal example

    import sys
    
    from PySide6.QtGui import QTextCursor, QTextBlockFormat
    from PySide6.QtWidgets import QApplication, QTextEdit
    
    
    if __name__ == "__main__":
        app = QApplication([])
        text_edit = QTextEdit()
        document = text_edit.document()
        text_cursor = QTextCursor(document)
        format = QTextBlockFormat(document.firstBlock().blockFormat())
        format.setTextIndent(50.0)
        text_cursor.setBlockFormat(format)
        text_edit.setTextCursor(text_cursor)
        text_edit.show()
        sys.exit(app.exec())
    
    

    While I'm here, do either of you know the units of setTextIndent(), setLeftMargin(), setTopMargin(), etc.? Is it pixels? Logical dots? Physical dots?



  • @duyjuwumu
    Yep, that's the right way to it (similar if you want to change the QFont, like adding bold, you have to get the current font, add bold, set it back).

    The units for the methods you ask about are "integers" :) If it;s anything I think it's pixels. Whatever they are. :)


Log in to reply