I'm trying to get the size of a text, so I can scale it accordingly to fit inside a box. But unfortunately the QFontMetrics.width() seems to give wrong outputs.

Here's a code that draws a text, and uses values from QFontMetrics to draw a rect that should be similar size. But it's not. As you can see in the picture below, the values from QFontMetrics (drawn rect) are about half of the one that I'm drawing. And unfortunately I can't just multiply it by 2, because depending on the text, the factor might be 1.85 or 1.95.

from PyQt5 import QtGui
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtGui import QPainter, QTextDocument, QFont, QFontMetrics
from PyQt5.QtCore import QRect, Qt, QRectF
import sys

font = QFont("times",10)
fm = QFontMetrics(font)



class Window(QMainWindow):
    def __init__(self):
        super().__init__()

        self.InitWindow()

    def InitWindow(self):
        self.setWindowIcon(QtGui.QIcon("icon.png"))
        self.show()

    def paintEvent(self, event):
        painter = QPainter(self)

        painter.setFont(font)

        sText = 'Hello World!'
        painter.drawText(0,100, sText)

        pixelsWide = fm.width(sText)
        pixelsHigh = fm.height()
        painter.drawRect(0, 100, pixelsWide, pixelsHigh)




App = QApplication(sys.argv)
window = Window()
sys.exit(App.exec())

enter image description here

1

There are 1 best solutions below

0
On BEST ANSWER

As explained in the QFont documentation:

Note that a QGuiApplication instance must exist before a QFont can be used.

This obviously including usage of the QFont as a QFontMetrics constructor.

The reason is simply logic and quite obvious: the QApplication must be aware of the UI environment in order to properly compute font metrics, which might depend on the paint device they're going to be drawn upon. Consider the common case of font scaling or High DPI settings: without a QGuiApplication, Qt has absolutely no meanings of knowing those aspects, and QFont shouldn't (nor could) obviously take care of that in its constructor, as QFontMetrics wouldn't.

Move the QFont and QFontMetrics constructor somewhere else, which could be in any moment after the QApplication creation and before their actual usage.