テキストの正確なピクセル幅を取得するには、QFontMetrics.boundingRectを使用する必要があります。
文字の左右の向きが考慮されるため、QFontMetrics.widthは使用しないでください。これにより、多くの場合 (常にではありません)、全ピクセル幅より数ピクセル多いまたは少ない結果が得られます。
したがって、ラベル テキストのピクセル幅を計算するには、次のようなものを使用します。
width = label.fontMetrics().boundingRect(label.text()).width()
編集
QFontMetrics
文字列の「幅」を計算するために使用できる3 つの異なる方法があります: size()
、width()
およびboundingRect()
。
ただし、すべてわずかに異なる結果が得られますが、すべての状況で一貫して正確なピクセル幅を返すものはないようです。どちらが最適かは、現在使用されているフォント ファミリと、文字列の先頭と末尾にある特定の文字に大きく依存します。
3 つの方法をテストするスクリプトを以下に追加しました。私にとっては、このboundingRect
方法が最も一貫した結果をもたらします。他の 2 つの方法は、やや幅が広すぎるか、セリフ フォントが使用されている場合に 2 番目のテキスト サンプルが切り取られる傾向があります (これは、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_())