About deprecation of QFontMetrics::width()

With any new version of the Qt toolkit comes some clean-up of its APIs to keep it clean, consistent, and future-proof. Part of this clean-up is to rename API functions to make it more clear what they actually do.

Starting with Qt 5.11, the QFontMetrics::width() function was deprecated. You could still compile code that uses this function, but since it is marked obsolete, you were encouraged to port away from it.

So what is unclear or not consistent about it? The function name and signature suggest that you can retrieve the width of a text string (or single character) taking into account the metrics of a specific font. Such metrics are needed to create widget layouts that automatically adapt to user specified fonts or different system display DPIs.

Reading the API description, the result is actually not the width. The graphics shown at https://doc.qt.io/qt-5/qfontmetrics-obsolete.html#width illustrates that there is a difference between the horizontal advance, i.e. the number of pixels from one character to the next character, and the bounding rectangle width, which is needed to encompass all pixels including so called bearings that can overlap the next or the previous character.

Since it was not clear from the confusingly named function QFontMetrics::width() that it actually returned the horizontal advance, instead of the bounding width, this method is now obsolete. You must port to either QFontMetrics::horizontalAdvance() or QFontMetrics::boundingRect().width().

Please make sure you are aware of the difference, and do not port blindly. I am pretty sure that in most cases QFontMetrics::boundingRect() is what you want, unless you are writing custom text shaping/layouting code. Using the wrong function can cause clipped text or text that suddenly wraps to the next line despite calculating the width that it needs.

3 thoughts on “About deprecation of QFontMetrics::width()”

  1. Thank you for this post! We are working on addressing deprecation warnings from 5.14.1 in LyX (which is Qt-based), and I’ve found this post to be helpful. Regarding transitioning away from QFontMetrics::width(), when you write “I am pretty sure that in most cases QFontMetrics::boundingRect() is what you want, unless you are writing custom text shaping/layouting code”, do I understand correctly that you are suggesting that it’s likely (unless you are writing custom text shaping/layouting code) that the user has been incorrectly using QFontMetrics::width()? More directly, my question is: if the user was correctly using QFontMetrics::width() before it was deprecated, they should indeed switch to QFontMetrics::horizontalAdvance(), right? Thanks for your help.

  2. I feel the documentation at https://doc.qt.io/qt-5/qfontmetrics-obsolete.html#width doesn’t warn clearly that you should probably have been using QFontMetrics::boundingRect() from the beginning. Me and another person both independently picked horizontalAdvance() when encountering this warning. If that’s the wrong thing to do, should the Qt documentation be changed?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s