Search code examples
qtalignmentqheaderview

Qt: QTreeView: center icon on header


For some columns from a QTreeView widget, I use an icon. The icon is set on

QVariant headerData (int section, Qt::Orientation orientation, int role) const{
    if(role ==  Qt::DecorationRole)
    {
        QIcon icon;
        if (section == 0) {
            icon.addFile(":/icon1");
        } else if (section == 1){
            icon.addFile(":/icon2");
        }
    }

    if(role ==  Qt::TextAlignmentRole)
    {
        return (Qt::AlignLeft + Qt::AlignVCenter);
    }

The header looks like this:

enter image description here

I want to align the icons with the text. TextAlignmentRole only works for text, but not for the icons. How can I do that?

I also tried by setting the default alignment:

m_treeview->header()->setDefaultAlignment(Qt::AlignCenter); but no luck.


Solution

  • In order to center icon with text you will have to implement your own proxy style to create this specific style behavior.

    #include <QProxyStyle>
    #include <QPainter>
    
    class HeaderProxyStyle : public QProxyStyle
    {
    public:
        void drawControl(ControlElement oCtrElement, const QStyleOption * poStylrOptionption, QPainter * poPainter, const QWidget * poWidget = 0) const;
    
    };
    

    Center icon with text implementation

        void HeaderProxyStyle::drawControl(ControlElement oCtrElement, const QStyleOption *poStylrOptionption, QPainter *poPainter, const QWidget *poWidget) const
        {
            // Header label?
            if (oCtrElement == CE_HeaderLabel) {
                // YES - Allocate style option header
                QStyleOptionHeader *poStyleOptionHeader =
                        (QStyleOptionHeader *) poStylrOptionption;
    
                // Get header icon
                QIcon oIcon = qvariant_cast<QIcon>(poStyleOptionHeader->icon);
    
                // Icon is valid?
                if(oIcon.isNull()){
                    // No - Draw text header
                    QProxyStyle::drawControl(oCtrElement, poStylrOptionption, poPainter, poWidget);
                    return;
                }
    
                // Set icon size 16x16
                QSize oIconSize = QSize(16,16);
    
                // Get header section rect
                QRect oRect = poStyleOptionHeader->rect;
    
                // Create header icon pixmap
                QPixmap oIconPixmap = oIcon.pixmap(oIconSize.width(),oIconSize.height());
    
                // Calculate header text width
                int iTextWidth = poStyleOptionHeader->fontMetrics.width(poStyleOptionHeader->text);
    
                QRect oCenterRec = QRect(oRect.left(),
                                        oRect.top() + (oRect.height - iTextSize)/2,
                                        oIconPixmap.width(),oIconPixmap.height());
    
    
                QRect oTextRect = QRect(oCenterRec.left()+ oIconSize.width(),
                                  oCenterRec.top(), oCenterRec.width() + iTextWidth, oCenterRec.height());
                // Draw icon
                poPainter->drawPixmap(oCenterRec, oIconPixmap);
                // Draw text
                poPainter->drawText(oTextRect, poStyleOptionHeader->text);
                return;
            }
            QProxyStyle::drawControl(oCtrElement, poStylrOptionption, poPainter, poWidget);
    
        }
    

    Then apply this header style in your tree view

    // Set header style
    m_treeview->header()->setStyle(&m_oHeaderStyle);