Qt-如何获取QLabel中字符串的像素长度?

2024-05-14 00:26:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个固定宽度的QLabel。
我需要(定期)检查整个字符串是否符合QLabel的当前宽度,以便可以适当地调整它的大小。

为此,我需要获取字符串的“像素长度”。
(显示字符串所需的水平像素总数)。
应该注意的是,QLabel的点大小从不改变。

Example of 'Pixel Width' of a string

我不能简单地检查出现的字符数量,因为有些字符是下标/上标的,并且对整个字符串的宽度的贡献不同。
(这意味着像素宽度和字符数量之间没有简单的关系)

有没有什么抽象的,超方便的函数?

规格:
Python 2.7.1
PyQt4
Windows 7


Tags: 函数字符串数量宽度关系windows水平像素
1条回答
网友
1楼 · 发布于 2024-05-14 00:26:23

要获得文本的精确像素宽度,必须使用QFontMetrics.boundingRect

不要使用QFontMetrics.width,因为它考虑了字符的左右方向。这通常(但并非总是)会导致多个像素或小于整个像素宽度的结果。

因此,要计算标签文本的像素宽度,请使用类似于:

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

编辑

有三种不同的QFontMetrics方法可用于计算字符串的“宽度”:^{}^{}^{}

然而,尽管它们给出的结果略有不同,在所有情况下,它们中的任何一个似乎都不会一致地返回精确的像素宽度。哪种字体最好主要取决于当前使用的字体系列以及字符串的开头和结尾处的特定字符。

我在下面添加了一个测试这三种方法的脚本。对我来说,boundingRect方法给出了最一致的结果。其他两个方法可能会稍微太宽,或者在使用serif字体时剪裁第二个文本示例(这是在Linux上的PyQt 4.9和qt4.8)。

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_())

相关问题 更多 >