View Single Post
Old 08-25-2025, 05:34 PM   #591
wrCisco
Connoisseur
wrCisco ought to be getting tired of karma fortunes by now.wrCisco ought to be getting tired of karma fortunes by now.wrCisco ought to be getting tired of karma fortunes by now.wrCisco ought to be getting tired of karma fortunes by now.wrCisco ought to be getting tired of karma fortunes by now.wrCisco ought to be getting tired of karma fortunes by now.wrCisco ought to be getting tired of karma fortunes by now.wrCisco ought to be getting tired of karma fortunes by now.wrCisco ought to be getting tired of karma fortunes by now.wrCisco ought to be getting tired of karma fortunes by now.wrCisco ought to be getting tired of karma fortunes by now.
 
Posts: 50
Karma: 605108
Join Date: Apr 2016
Device: none
I wanted to improve and generalize the first-words-then-everywhere wrapping of text for the plain text of QLabels, so I'm partially rewriting the code of my WrappingCheckBox widget to use QTextBoundaryFinder to split words and graphemes in a text, and I stumbled upon a small incompatibility between pyqt5 and pyside6: while in pyside6 you can iterate over qt enums, in pyqt5 you can't. Do you know if there is a more clever way to do what I'm doing with 'boundary_reasons' in the following function (an optional parameter which, if None, is assigned all the enumeration's values combined)?

Code:
from functools import reduce
from plugin_utils import QtCore

def tokenize_text(
            text: str,
            boundary_type: QtCore.QTextBoundaryFinder.BoundaryType,
            boundary_reasons: QtCore.QTextBoundaryFinder.BoundaryReason | None = None) -> list[str]:
        """
        Divide text in a list of tokens based on boundary_type.
        boundary types: Grapheme, Word, Line, Sentence
        """
        if boundary_reasons is None:
            try:
                # BreakOpportunity doesn't come up while iterating over BoundaryReason flags
                # (PySide 6.9), so I use it as the initializer of the reduce function
                boundary_reasons = reduce(
                    lambda x, y: x | y,
                    QtCore.QTextBoundaryFinder.BoundaryReason,
                    QtCore.QTextBoundaryFinder.BoundaryReason.BreakOpportunity
                )
            except TypeError:
                # PyQt5 doesn't allow iterations over Qt enums
                boundary_reasons = (
                    QtCore.QTextBoundaryFinder.BoundaryReason.StartOfItem
                    | QtCore.QTextBoundaryFinder.BoundaryReason.EndOfItem
                    | QtCore.QTextBoundaryFinder.BoundaryReason.MandatoryBreak
                    | QtCore.QTextBoundaryFinder.BoundaryReason.SoftHyphen
                    | QtCore.QTextBoundaryFinder.BoundaryReason.BreakOpportunity
                )
        tbf = QtCore.QTextBoundaryFinder(boundary_type, text)
        tokens = []
        pos = prev = tbf.position()
        while True:
            pos = tbf.toNextBoundary()
            if pos == -1:
                break
            if pos != prev and boundary_reasons & tbf.boundaryReasons():
                token = text[prev:pos]
                tokens.append(text[prev:pos])
                prev = pos
        return tokens
I found a couple of Stack Overflow answers that address the issue, but the solution proposed seems way too complex for my limited use case (https://stackoverflow.com/questions/...representation, https://stackoverflow.com/questions/...-typedef-for-q).
wrCisco is offline   Reply With Quote