Ответ 1
Чтобы получить точную ширину пикселя текста, вы должны использовать QFontMetrics.boundingRect.
Не используйте QFontMetrics.width, так как он учитывает левый и правый подшипники символов. Это часто (но не всегда) приводит к результатам, которые могут быть в несколько пикселей больше или меньше, чем полная ширина пикселя.
Итак, чтобы вычислить ширину пикселя текста метки, используйте что-то вроде:
width = label.fontMetrics().boundingRect(label.text()).width()
ИЗМЕНИТЬ
Существуют три разных метода QFontMetrics
, которые можно использовать для вычисления "ширины" строки: size()
, width()
и boundingRect()
.
Однако, хотя все они дают несколько разные результаты, ни один из них, похоже, не всегда возвращает точную ширину пикселя при любых обстоятельствах. Какой из них лучше всего зависит в основном от текущего используемого семейства шрифтов и от того, какие конкретные символы находятся в начале и конце строки.
Я добавил ниже script, который проверяет три метода. Для меня метод boundingRect
дает наиболее последовательные результаты. Другие два метода имеют тенденцию быть либо слишком широкими, либо зажимать второй образец текста при использовании шрифта с засечками (это с PyQt 4.9 и Qt 4.8 в 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_())