Qt - 如何获取QLabel中字符串的像素长度?
我有一个固定宽度的 QLabel。
我需要定期检查这个 QLabel 的宽度是否能容纳整个字符串,这样我才能适当地调整它的大小。
为此,我需要获取字符串的“像素长度”。
(也就是显示这个字符串所需的总水平像素数)。
需要注意的是,QLabel 的字体大小是不会改变的。
我不能仅仅检查字符的数量,因为有些字符是下标或上标,它们对整个字符串的宽度影响不同。
(这就是说,像素宽度和字符数量之间没有简单的关系)
有没有什么简单方便的函数可以做到这一点呢?
规格:
Python 2.7.1
PyQt4
Windows 7
1 个回答
35
要准确获取文本的像素宽度,你需要使用 QFontMetrics.boundingRect。
不要使用 QFontMetrics.width,因为它会考虑字符的左右边距。这通常(但并不总是)会导致结果比实际的像素宽度多或少几个像素。
所以,要计算标签文本的像素宽度,可以使用类似下面的代码:
width = label.fontMetrics().boundingRect(label.text()).width()
编辑
有三种不同的 QFontMetrics
方法可以用来计算字符串的“宽度”: size()
、 width()
和 boundingRect()
。
不过,虽然它们的结果略有不同,但 没有一个 方法在所有情况下都能始终返回准确的像素宽度。哪个方法最好,主要取决于当前使用的字体和字符串开头和结尾的特定字符。
我下面添加了一个脚本,用来测试这三种方法。对我来说,boundingRect
方法给出的结果最为一致。其他两个方法往往要么稍微宽一点,要么在使用衬线字体时会剪切掉第二个文本样本(这是在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_())