【问题标题】:Qt - How to get the pixel length of a string in a QLabel?Qt - 如何在 QLabel 中获取字符串的像素长度?
【发布时间】:2011-12-26 06:23:14
【问题描述】:

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

为此,我需要获取字符串的“像素长度”。
(显示字符串所需的水平像素总量)。
需要注意的是,QLabel 的磅值永远不会改变。

我不能简单地检查存在的字符数量,因为有些字符是下标/上标,并且对整个字符串的宽度有不同的影响。
(也就是说像素宽度和字符数量没有简单的关系)

是否有任何抽象的、超级方便的功能呢?

规格:
Python 2.7.1
PyQt4
视窗 7

【问题讨论】:

    标签: python pyqt width pyqt4 qlabel


    【解决方案1】:

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

    不要使用QFontMetrics.width,因为它考虑了字符的左右方位。这通常(但不总是)会导致结果可能比完整像素宽度多或少几个像素。

    因此,要计算标签文本的像素宽度,请使用以下内容:

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

    编辑

    可以使用三种不同的QFontMetrics 方法来计算字符串的“宽度”:size()width()boundingRect()

    然而,尽管它们都给出了略微不同的结果,没有一个似乎在所有情况下都能始终如一地返回准确的像素宽度。哪个最好主要取决于当前使用的字体系列以及字符串开头和结尾的特定字符。

    我在下面添加了一个测试这三种方法的脚本。对我来说,boundingRect 方法给出了最一致的结果。其他两种方法要么稍微太宽,要么在使用 serif 字体时剪裁第二个文本样本(这适用于 Linux 上的 PyQt 4.9 和 Qt 4.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_())
    

    【讨论】:

    • @AntiEarth。方位可以是负数,因此如果在调整大小时考虑到它们,标签文本可能会在边缘被裁剪。只有boundingRect 保证始终给出文本的完整像素宽度。
    • 它没有考虑下标,是吗?只是磅值?
    • @AntiEarth。请看我更新的答案。下标和磅值对我来说似乎不是重要因素 - 但在 Windows 上可能会有所不同。
    • @AntiEarth。默认情况下,标签会自动调整大小以适合自己的内容。他们这样做的主要原因之一是为了让用户不必为了设置固定宽度而尝试计算内容的尺寸。我很确定有更简单的方法可以解决您遇到的所有布局问题。但正如我在您之前的一个问题中所评论的那样:实现这一目标的最实用方法是发布一些真实的、可测试的代码(或 ui 文件)来演示这些问题。
    • 在您发表评论后使用 .adjustSize() 解决。谢谢!
    猜你喜欢
    • 2012-05-02
    • 1970-01-01
    • 1970-01-01
    • 2010-09-18
    • 2019-12-08
    • 2019-01-13
    • 1970-01-01
    • 2011-05-13
    • 1970-01-01
    相关资源
    最近更新 更多