views:

458

answers:

1

I have a QTableView which I am setting a custom QStyledItemDelegate on.

In addition to the custom item painting, I want to style the row's background color for the selection/hovered states. The look I am going for is something like this KGet screenshot: KGet's Row Background

Here is my code:

void MyDelegate::paint( QPainter* painter, const QStyleOptionViewItem& opt, const    QModelIndex& index ) const
{
    QBrush backBrush;
    QColor foreColor;
    bool hover = false;
    if ( opt.state & QStyle::State_MouseOver )
    {
           backBrush = opt.palette.color( QPalette::Highlight ).light( 115 );
           foreColor = opt.palette.color( QPalette::HighlightedText );
           hover = true;
    }
    QStyleOptionViewItemV4 option(opt);
    initStyleOption(&option, index);
    painter->save();
    const QStyle *style = option.widget ? option.widget->style() : QApplication::style();
    const QWidget* widget = option.widget;
    if( hover )
    {
            option.backgroundBrush = backBrush;
    }
    painter->save();
    style->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter, widget);
    painter->restore();
    switch( index.column() )
    {
    case 0: // we want default behavior
        style->drawControl(QStyle::CE_ItemViewItem, &option, painter, widget);
        break;
    case 1:
    // some custom drawText
    break;
    case 2:
    // draw a QStyleOptionProgressBar
    break;
    }
    painter->restore();
}

The result is that each individual cell receives the mousedover background only when the mouse is over it, and not the entire row. It is hard to describe so here is a screenshot: The result of the above code

In that picture the mouse was over the left most cell, hence the highlighted background.. but I want the background to be drawn over the entire row.

How can I achieve this?

Edit: With some more thought I've realized that the QStyle::State_MouseOver state is only being passed for actual cell which the mouse is over, and when the paint method is called for the other cells in the row QStyle::State_MouseOver is not set.

So the question becomes is there a QStyle::State_MouseOver_Row state (answer: no), so how do I go about achieving that?

A: 

You need to be telling the view to update its cells when the mouse is over a row, so I would suggest tracking that in your model. Then in the paint event, you can ask for that data from the model index using a custom data role.

Caleb Huitt - cjhuitt
How would the model know if the mouse is over a row? That seems to belong strictly to the view?
Casey
@Casey: You will need cooperation between the model and the view. When the mouse goes over a row, you can tell the model such, and then the model would need to tell the view to redraw the necessary rows, and the delegate would need to draw the appropriate background for what you want.
Caleb Huitt - cjhuitt