How to add Icon into QHeaderView



  • I would like to add an Icon right beside the text in the QHeaderView.
    If the Icon will be added the text in the QHeaderView-Section should be elided if necessary.

    To solve this problem I do the following:

    In MyHeaderView::paintSection(painter rect , index)

    QRect iconRect = iconPixmap.rect();
    QRect textRect = rect;
    textRect.setWidth(textRect.width() - iconRect.width());
    // textRect will contain the available space for the text
    
    QFont theFont = ... // get actual QHeaderView text font
    QFontMetrics fontMetrics(theFont);         
    QString elidedText = fontMetrics.elidedText(text, Qt::ElideRight, textRect.width());
    // so I get the elidedText if necessary
    model() -> setHorizontalHeaderText(index, elidedText)
    // setting the text in the model, but without emitting a dataChanged
    QHeaderView::paintSection(painter, textRect, logicalIndex);
    

    This is a little bit complicated, but seems to be working (at least when the alignment for the text is Qt::AlignLeft)
    but is not working for text which is aligned Qt::AlignRight.

    Is there another (maybe much easier) solution for icons in QHeaderViews ?



  • Got a solution for that question by myself.

    The solution works also for right aligned text.

    void MyHeaderView::paintSection(QPainter* painter, const QRect& rect, int logicalIndex) const
    {
    // The Icon to draw on right of the header text is in iconPixmap
    QRect iconRect = iconPixmap.rect();
    QRect textRect = rect;
    textRect.setWidth(textRect.width() - iconRect.width());

      QFont myFont = getFont();  // delivers the font for for the header text
      QFontMetrics fontMetrics(myFont);
      
      // determine the elided text which will be printed for the available width
      // m_header_padding is the padding of the headerview section
      QString elidedText = fontMetrics.elidedText(text, Qt::ElideRight, textRect.width() - m_header_padding * 2);
      
      // Drawing procedure
      // First draw without text over the complete header section size
      // this will draw the background and the borders etc. for the complete header section         
      model() -> setHorizontalHeaderText(index, QString());  // set text in model without emitting datachanged
      QHeaderView::paintSection(painter, rect, logicalIndex);
      
      // now draw the (possibly elided) text into the header section
      model() -> setHorizontalHeaderText(logicalIndex, elidedText);
      QHeaderView::paintSection(painter, textRect, logicalIndex);
      
      // Now restore the header section text in the model 
      model() -> setHorizontalHeaderText(logicalIndex, text);
      
      // Draw the icon
      // center icon vertical
      int iconHeight = iconRect.height();
      int headerHeight = rect.height();
      int offset = 0;
      if (iconHeight < headerHeight) {
         offset = (headerHeight - iconHeight) / 2;
      }    
      painter -> setClipRect(rect);
      painter -> drawPixmap(textRect.right()-1, rect.top() + offset, iconRect.width(), iconRect.height(), iconPixmap);
      painter -> setClipRect(rect);
    

    }


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.