Para obtener el píxel de ancho precisa del texto, debe utilizar QFontMetrics.boundingRect.
No utilice QFontMetrics.width, ya que tiene en cuenta el rumbo izquierdo y derecho de los caracteres. Esto a menudo (pero no siempre) dará lugar a resultados que pueden ser varios píxeles más o menos que el ancho de píxel completo.
Por lo tanto, para calcular el píxel de ancho del texto de la etiqueta, usar algo como:
width = label.fontMetrics().boundingRect(label.text()).width()
EDITAR
Hay tres diferentes QFontMetrics
métodos que pueden ser utilizados para calcular el "ancho "de una cadena: size()
, width()
y boundingRect()
.
Sin embargo, aunque todos dan resultados ligeramente diferentes, ninguno de ellos parece devolver consistentemente el ancho exacto de píxeles en todas las circunstancias. Cuál es el mejor depende principalmente de la familia de fuentes actual en uso y en qué caracteres particulares se encuentran al principio y al final de la cadena.
He añadido debajo una secuencia de comandos que prueba los tres métodos. Para mí, el método boundingRect
ofrece los resultados más consistentes. Los otros dos métodos tienden a ser demasiado anchos o recortar la segunda muestra de texto cuando se utiliza una fuente serif (esto es con PyQt 4.9 y Qt 4.8 en 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_())
¡Quiero que se tengan en cuenta los rodamientos, pero gracias de todos modos! –
@AntiEarth. Los rodamientos pueden ser negativos, por lo que si se tienen en cuenta para el cambio de tamaño, el texto de la etiqueta puede recortarse en los bordes. Solo se garantiza que el 'boundingRect' proporciona siempre el ancho de píxel completo del texto. – ekhumoro
No tiene en cuenta la subscripción, ¿o sí? Solo punto de tamaño? –