简体   繁体   English

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

[英]Qt - How to get the pixel length of a string in a QLabel?

I have a QLabel of a fixed width.我有一个固定宽度的 QLabel。
I need to check (periodically) that the entire string fits inside the QLabel at its current width, so I can resize it appropriately.我需要(定期)检查整个字符串是否以当前宽度容纳在 QLabel 内,以便我可以适当地调整它的大小。

To do this, I need to obtain the 'pixel length' of the string.为此,我需要获取字符串的“像素长度”。
(The total amount of horizontal pixels required to display the string). (显示字符串所需的水平像素总数)。
It should be noted that the point size of the QLabel never changes.需要注意的是 QLabel 的点大小永远不会改变。

字符串的“像素宽度”示例

I can not simply check the amount of characters present, since some characters are subscript / superscript and contribute differently to the width of the entire string.我不能简单地检查存在的字符数量,因为有些字符是下标/上标,并且对整个字符串的宽度有不同的贡献。
(This is to say there is no simple relationship between pixel width and the amount of characters) (这就是说像素宽度和字符数没有简单的关系)

Is there any abstracted, super conveniant function for this?是否有任何抽象的,超级方便的功能?

Specs:眼镜:
Python 2.7.1蟒蛇 2.7.1
PyQt4 PyQt4
Windows 7 Windows 7的

To get the precise pixel-width of the text, you must use QFontMetrics.boundingRect .要获得文本的精确像素宽度,您必须使用QFontMetrics.boundingRect

Do not use QFontMetrics.width , because it takes into account the left and right bearing of the characters.不要使用QFontMetrics.width ,因为它考虑了字符的左右方位。 This will often (but not always) lead to results which can be several pixels more or less than the full pixel-width.这通常(但不总是)导致结果可能比全像素宽度多或少几个像素。

So, to calculate the pixel-width of the label text, use something like:因此,要计算标签文本的像素宽度,请使用以下内容:

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

EDIT编辑

There are three different QFontMetrics methods which can be used to calculate the "width" of a string: size() , width() and boundingRect() .有三种不同的QFontMetrics方法可用于计算字符串的“宽度”: size()width()boundingRect()

However, although they all give slightly different results, none of them seems to consistently return the exact pixel-width in all circumstances.然而,尽管它们给出的结果略有不同,但它们似乎都没有在所有情况下始终返回精确的像素宽度。 Which one is best depends mostly on the current font-family in use and on which particular characters are at the beginning and end of the string.哪个最好主要取决于当前使用的字体系列以及字符串开头和结尾的特定字符。

I have added below a script that tests the three methods.我在下面添加了一个测试这三种方法的脚本。 For me, the boundingRect method gives the most consistent results.对我来说, boundingRect方法给出了最一致的结果。 The other two methods tend to be either slightly too wide, or clip the second text sample when a serif font is used (this is with PyQt 4.9 and Qt 4.8 on Linux).其他两种方法往往要么稍微太宽,要么在使用衬线字体时剪辑第二个文本示例(这是在 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_())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM