PDA

View Full Version : QLabel: Resize font to contentsRect



Ghal_Maraz
22nd July 2016, 13:05
Hi,

I try to implement an algorithm to resize the font of a QLabel, so that the text fits. For that I am using contentsRect() and QFontMetrics. I just decrease the font size as long as the boundingRect is bigger than the contentsRect. This works fine as long as the frameShape is NoFrame. As soon as I change it to StyledPanel (and I have to, because I want to use Stylesheets), it no longer works. It seems as if the area for the content is always a bit smaller than contentsRect.

To check this I tried the following scenario:
Under Windows a label with fontsize 12 and the text "this is a test" with active word wrap and MS sans serif. QFontMetrics::width("this is a test") returns 84. So I conclude that the contentsRects needs a width of at least 84px to hold the whole text in one line and avoid any word wrap.
But in fact it needs to be 87px to do so. In this case the label width is 89px, the left and righ contentsMargins are each 1px. So contentsRects seems to be as expected. Furthermore the difference between expected and necessary width seems to depend on the fontsize. For example for Fontsize 24 and the same scenario, I need 7 additional pixels.

The word wrap is just to visualize, if the text fits. If I turn word wrap off and set the contentsRects width to 84px, the text is cut off.

Does anyone know, why it behaves like that? Or does anyone have another solution to implement this feature?

Thanks and best regards,
Ghal_Maraz

anda_skoa
22nd July 2016, 13:30
If you look at the implementation of QLabel::paintEvent() you'll see that it uses the contents rect with additional label margin removed:
https://code.woboq.org/qt5/qtbase/src/widgets/widgets/qlabel.cpp.html#_ZN6QLabel10paintEventEP11QPaintEv ent

Cheers,
_

Ghal_Maraz
25th July 2016, 15:15
Thanks for your reply.

I checked the margin and it is configured to zero and also label's margin() returns zero.
I think it must be somehow connected to StyledPanel as frameShape.

Ghal_Maraz
27th July 2016, 10:25
I finally found the reason for this behavior in the function QLabelPrivate::documentRect in qlabel.cpp:


int m = indent;
if (m < 0 && q->frameWidth()) // no indent, but we do have a frame
m = q->fontMetrics().width(QLatin1Char('x')) / 2 - margin;

When the label's frameShape is set to StyledPanel, frameWidth returns 1.