Получение длины текста QLabel в пикселях и символах без html тегов

Мне нужно получить длину QLabel в пикселях, QLabel содержит некоторый HTML:

main.py:

from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QHBoxLayout


class Win(QWidget):
    def __init__(self):
        super().__init__()
        self.label = QLabel('<font style = "color:red">а</font>')
        self.l = QHBoxLayout()
        self.l.addWidget(self.label)
        self.setLayout(self.l)
        self.show()
        print(self.label.fontMetrics().boundingRect(self.label.text()).width())
if __name__ == '__main__':
    app = QApplication([])
    win = Win()
    app.exec_()

Код возвращает 200 пикселей, что явно больше.
Как решить эту проблему? По возможности подскажите как можно также получить длину текста в символах без тегов


Ответы (1 шт):

Автор решения: S. Nick

Текстовые виджеты Qt могут отображать форматированный текст,
заданный с использованием подмножества разметки HTML 4.
Виджеты, использующие QTextDocument, такие как QLabel и QTextEdit,
могут отображать форматированный текст, указанный таким образом.

qreal QTextDocument::idealWidth() const

Возвращает идеальную ширину текстового документа.
Идеальная ширина — это фактически используемая ширина документа без учета дополнительных выравниваний.

import sys
from PyQt5.Qt import *


class Win(QWidget):
    def __init__(self):
        super().__init__()
        
        html = '''
        <font style="color: red; 
            background-color: yellow;
            font-size: 27px;">
            Привет 1234567</font>
        '''
                
        self.label = QLabel()
        self.textDocument = QTextDocument(self.label)
        self.textDocument.setUseDesignMetrics(True)
        
        self.label_2 = QLabel('Привет 1234567')       # без html тегов
        font = self.label_2.font()
        font.setPointSize(20)
        metrics = QFontMetrics(font)
        width = metrics.width(self.label_2.text())
        self.label_2.setFixedWidth(width)
        self.label_2.setFont(font)
        
        self.frame_left_top = QFrame()
        
        self.frame_left_bottom = QFrame()
        self.label_2.setParent(self.frame_left_bottom)
        
        self.layout = QHBoxLayout(self.frame_left_top)
        self.layout.setContentsMargins(0, 0, 0, 0)
        self.layout.addWidget(self.label)
        
        self.textEdit = QTextEdit()
        self.textEdit.textChanged.connect(self._text_changed)
        self.textEdit.setHtml(html)
        
        self.main_layout = QGridLayout(self)
        self.main_layout.addWidget(self.frame_left_top, 0, 0)
        self.main_layout.addWidget(self.frame_left_bottom, 1, 0)
        self.main_layout.addWidget(self.textEdit, 0, 1, 2, 1)
        self.main_layout.setColumnStretch(0, 1)
        self.main_layout.setColumnStretch(1, 1)

        QTimer.singleShot(3000, lambda: self.textEdit.setHtml(
            '''<i  style="color: blue; 
                   background-color: #D98C00; 
                   font-size: 30px;">
                 Привет 1234567
               </i>
            '''))

    def _text_changed(self):
        text = self.textEdit.toHtml()

        self.label.setText(text)

        self.textDocument.setHtml(text)
        print(f'label   = {self.textDocument.idealWidth()}') 

        labelWidth_2 = self.label_2.fontMetrics().width(
            self.label_2.text())
        print(f'label_2 = {labelWidth_2}; '
              f'geometry={self.label_2.geometry()};\n')
    

if __name__ == '__main__':
    app = QApplication(sys.argv)
    win = Win()
    win.resize(600, 100)
    win.show()
    sys.exit(app.exec())

введите сюда описание изображения

введите сюда описание изображения

введите сюда описание изображения

введите сюда описание изображения

→ Ссылка