Please nominate your Qt Champions for 2021! https://forum.qt.io/topic/132134/looking-for-the-2021-qt-champions

QTableView / QItemDelegate customize selection



  • Hi everyone

    because the user must be able to see the row's background-color i want to replace the default row-selection-style with a 1px frame at the rows/cells borders.
    That's why i subclassed QItemDelegate and implemented my own paint-Method.

    void QSelectionItemDelegate::paint( QPainter *painter_, const QStyleOptionViewItem &option_, const QModelIndex &index_ ) const
    {
        QStyleOptionViewItem opt = option_;
        this->QItemDelegate::paint( painter_, opt, index_ );
        if ( option_.state & QStyle::State_Selected )
        {
            painter_->setPen( Qt::red );
            painter_->drawRect( option_.rect );
        }
    }
    

    Drawing the red frame works perfectly, but the default row-selection-style ( blue filled rect ) is visible as well. How can i get rid of the default selection-style and only draw my red frame?

    greetings Toby


  • Lifetime Qt Champion

    Remove the selected state before calling paint base method.

    And please use QStyledItemDelegate - QItemDelegate is deprecated.



  • Works perfectly. Many thanks!

    
    void QSelectionItemDelegate::paint( QPainter *painter_, const QStyleOptionViewItem &option_, const QModelIndex &index_ ) const
    {
        // copying QStyleOptionViewItem for modification
        QStyleOptionViewItem opt = option_;
        // remove selected-flag
        if ( opt.state & QStyle::State_Selected )
            opt.state &= ~QStyle::State_Selected;
        
        // call base for normal painting
        QStyledItemDelegate::paint( painter_, opt, index_ );
    
        // grab original selected_state and draw selection-frame
        if ( option_.state & QStyle::State_Selected )
        {
            QRect r( opt.rect.left(), opt.rect.top(), opt.rect.width() - 1, opt.rect.height() - 1 );
            painter_->setPen( Qt::red );
            painter_->drawRect( r );
        }
    }
    

  • Lifetime Qt Champion

    @Toby said in QTableView / QItemDelegate customize selection:

    painter_->setPen( Qt::red );

    Even it's not applicable here you should use QPainter::Save()/restore() when you change the painter's state inside such functions to avoid spurious paintings when the painter is used afterwards.



  • Thanks for the advice. :-)
    Last Question: is there a (good) way to find out whether the row above or below is also in selected_state ?


  • Lifetime Qt Champion

    @Toby said in QTableView / QItemDelegate customize selection:

    is there a (good) way to find out whether the row above or below is also in selected_state ?

    No, not with QStyleOptionViewItem. You need access to the selection model somehow.



  • ok, thx.


Log in to reply