Search code examples
pythonpyqtiterationqtexteditqtextdocument

How do QTextBlock or QTextFrame iterators work in PyQt


When working with a QTextDocument, Qt provides iterators (such as QTextBlock.iterator) to move through the contents. The documentation here shows the C++ code, but obviously the ++ operator doesn't work and the PyQt version doesn't seem to have anything like a next() function.

So how do you make the iterator iterate?

The documentation for QTextFrame.begin (which returns the iterator) has a broken link to "STL-style-Iterators", but I can't find any details of these being implemented in Python.


Solution

  • The documentation shows that in PyQt, iterator objects support __iadd__ and __isub__. This allows you to use, e.g. it += 1 instead of ++it.

    Here's a small demo:

    # from PyQt5.QtWidgets import QApplication, QTextEdit
    from PyQt4.QtGui import QApplication, QTextEdit
    
    app = QApplication(['test'])
    
    edit = QTextEdit()
    edit.setText('one<b>two</b>three<br>')
    
    it = edit.document().firstBlock().begin()
    while not it.atEnd():
        fragment = it.fragment()
        if fragment.isValid():
            print(fragment.text())
        it += 1
    

    Output:

    one
    two
    three