Qt-получить длину пикселя строки в QLabel

У меня есть QLabel фиксированной ширины.
Мне нужно проверить (периодически), что вся строка помещается внутри QLabel на его ширину, поэтому я могу изменить его соответствующим образом.

для этого мне нужно получить "длину пикселя" строки.
(Общее количество горизонтальных пикселей, необходимых для отображения строки).
Следует отметить, что размер QLabel никогда не меняется.

Example of 'Pixel Width' of a string

Я не могу просто проверить количество символов присутствует, так как некоторые символы являются subscript / superscript и по-разному влияют на ширину всей строки.
(Это означает, что нет простой связи между шириной пикселя и количеством символов)

есть ли какая-либо абстрактная, супер удобная функция для этого?

технические характеристики:
Python 2.7.1
В составе PyQt4
Windows 7

1 ответов


чтобы получить точную ширину пикселя текста, вы должны использовать QFontMetrics.boundingRect.

Не используйте QFontMetrics.ширина, потому что он учитывает левый и правый подшипник символов. Это часто (но не всегда) приводит к результатам, которые могут быть на несколько пикселей больше или меньше полной ширины пикселя.

Итак, чтобы вычислить ширину пикселя текста метки, используйте что-то например:

width = label.fontMetrics().boundingRect(label.text()).width()

редактировать

есть три разных QFontMetrics методы, которые можно использовать для вычисления "ширины" строки:size(), width() и boundingRect().

однако, хотя все они дают немного разные результаты,никто из них кажется, последовательно возвращает точную ширину пикселя при любых обстоятельствах. Какой из них лучше всего зависит в основном от тока font-семейство используемых и на котором определенные символы находятся в начале и конце строки.

я добавил ниже сценарий, который проверяет три метода. Для меня boundingRect метод дает наиболее достоверные результаты. Два других метода имеют тенденцию быть либо немного слишком широкими, либо обрезать второй образец текста при использовании шрифта с засечками (это с PyQt 4.9 и Qt 4.8 в Linux).

from PyQt4 import QtGui, QtCore

class Window(QtGui.QWidget):
    def __init__(self):
        QtGui.QWidget.__init__(self)
        self.setAutoFillBackground(True)
        self.setBackgroundRole(QtGui.QPalette.Mid)
        self.setLayout(QtGui.QFormLayout(self))
        self.fonts = QtGui.QFontComboBox(self)
        self.fonts.currentFontChanged.connect(self.handleFontChanged)
        self.layout().addRow('font:', self.fonts)
        for text in (
            u'H\u2082SO\u2084 + Be',
            u'jib leaf jib leaf',
            ):
            for label in ('boundingRect', 'width', 'size'):
                field = QtGui.QLabel(text, self)
                field.setStyleSheet('background-color: yellow')
                field.setAlignment(QtCore.Qt.AlignCenter)
                self.layout().addRow(label, field)
        self.handleFontChanged(self.font())

    def handleFontChanged(self, font):
        layout = self.layout()
        font.setPointSize(20)
        metrics = QtGui.QFontMetrics(font)
        for index in range(1, layout.rowCount()):
            field = layout.itemAt(index, QtGui.QFormLayout.FieldRole).widget()
            label = layout.itemAt(index, QtGui.QFormLayout.LabelRole).widget()
            method = label.text().split(' ')[0]
            text = field.text()
            if method == 'width':
                width = metrics.width(text)
            elif method == 'size':
                width = metrics.size(field.alignment(), text).width()
            else:
                width = metrics.boundingRect(text).width()
            field.setFixedWidth(width)
            field.setFont(font)
            label.setText('%s (%d):' % (method, width))

if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())