Question

I'm currently implementing a custom delegate, in part of which I need a QSpinBox to be drawn in the paint(..) method.

void Sy_floatingPointPD::paint( QPainter* painter,
                                const QStyleOptionViewItem& option,
                                const QModelIndex& index ) const
{
    painter->save();

    //  Paint check box.
    QStyleOptionSpinBox spOpt;
    spOpt.palette     = option.palette;
    spOpt.rect        = option.rect;
    spOpt.state       = option.state;
    spOpt.frame       = true;
    spOpt.stepEnabled = QAbstractSpinBox::StepUpEnabled |
                       QAbstractSpinBox::StepDownEnabled;

    style->drawComplexControl( QStyle::CC_SpinBox, &spOpt, painter );

    painter->restore();
}

Unfortunately it appears as:

Paint failure

As you can see the step buttons are drawn massive and only the down arrow appears. Interestingly the width of the buttons mirrors that of the first table column, despite option.rect being the size of the cell (which is correct, which is presumably why the frame is drawn correctly).

Any ideas what information I'm not giving QStyle?

Was it helpful?

Solution

Jens over at the qt-project forums answered this question, so I'll link to it here.

In short, there is a design flaw in the spin box drawing (at least in QGtkStyle) whereby it only uses the size of the option.rect, ignoring it's position. Although this perfectly reasonable in a 'normal' painting scenario because it maps to the widget origin, it fails when rendered in an item view due to the cell offset.

To solve this, move option.rect to the widget origin (i.e. move it's top left corner to (0,0)), and then translate the QPainter to take into account the cell offset.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top