Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QLabel Alignment - removing padding



  • Hi,

    After setting a QLabel's text alignment to "Qt::AlignLeft | Qt::AlignTop" I see the QLabel has padding left and top, more top:

    alt text

    Is it possible to remove this?

    I've tried numerous methods such as setMargin etc without luck.

    I've also tried using QFontMetrics to obtain the co-ordinates of the actual text but in order to get the alignment correct, adjustments to the code had to be made to the co-ordinates to align top left - I can't see this working for all font sizes:

    mValueLabel = new QLabel( this );

    // Set font
    QFont font = mValueLabel->font();
    font.setFamily( "Arial" );
    font.setPointSize( 172 );
    mValueLabel->setFont( font );

    mValueLabel->setText( "66" );

    QFontMetrics labelFontMetrics( font );
    QRect boundingRect = labelFontMetrics.tightBoundingRect( "66" );
    mValueLabel->setGeometry( -8, -40, boundingRect.width() + 10, boundingRect.height() + 40 );

    Result:

    alt text

    I'm sure there's a much better way of achieving this!

    Many thanks in advance for any input.


  • Moderators

    @CAM79
    there is some inner padding (indent) in the QLabel. But this can also be read up in the docs:

    If a label displays text, the indent applies to the left edge if alignment() is Qt::AlignLeft, to the right edge if alignment() is Qt::AlignRight, to the top edge if alignment() is Qt::AlignTop, and to the bottom edge if alignment() is Qt::AlignBottom.

    If indent is negative, or if no indent has been set, the label computes the effective indent as follows: If frameWidth() is 0, the effective indent becomes 0. If frameWidth() is greater than 0, the effective indent becomes half the width of the "x" character of the widget's current font().

    By default, the indent is -1, meaning that an effective indent is calculating in the manner described above.

    Effectively becomes:

    QLabel* label = ...;
    QFontMetrics fm(label->font());
    
    int labelMargin = label->margin();
    int labelIndent = label->indent();
    int frameWidth = label->frameWidth();
    
    if( labelIndent < 0 ) {
         if( frameWidth <= 0 )
             labelIndent = 0;
         else
             labelIndent = ( fm.width("x") / 2.0 );
    }
    int xCorr = labelMargin + labelIndent  + frameWidth;
    


  • @raven-worx Thanks for the reply. The space horizontally although not perfect to the edge I can handle, but the indent has no effect on the vertical space above and below the text. More investigation has revealed this maybe due to a border, but all attempts to remove this border has failed. The space above and below the text also increases with font size.


  • Moderators

    @CAM79
    then maybe you are talking about the font descent?
    (The descent is not relevant for numbers etc. But for character like g for example)



  • @raven-worx Having spend futher time with this, I understand that the space top and bottom is required for the descent and ascent of letters (e.g. tails that fall below the baseline) so actually I believe it is working correctly now.

    I spent time to complete the my original task to produce the following result:

    alt text

    The code to produce this for future reference is:

    mValueLabel = new QLabel( this );
    mValueLabel->setTextFormat( Qt::RichText );
    
    // Set font
    QFont font = mValueLabel->font();
    font.setFamily( "Arial" );
    font.setPointSize( 172 );
    mValueLabel->setFont( font );
    
    mValueLabel->setText( "66" );
    
    mValueLabel->setStyleSheet( "background-color: blue;" );
    
    QFontMetrics labelFontMetrics( font );
    QRect tightBoundingRect = labelFontMetrics.tightBoundingRect( "66" );
    
    int xOffset = labelFontMetrics.leftBearing( QChar( '6' ) ); // First character
    int yOffset = tightBoundingRect.y() + labelFontMetrics.ascent();
    
    mValueLabel->setGeometry( -xOffset, -( yOffset ), tightBoundingRect.width() + xOffset, tightBoundingRect.height() + yOffset );
    

    I think the setGeometry method where xOffset is added to the width should use the ascent but it works for now.

    Thanks for your input.


Log in to reply