PDA

View Full Version : How to draw background for editor widget created by QStyledItemDelegate



chiefaua
28th March 2008, 18:27
Hello

I've got following question:
I have a view displaying some progress through a custom delegate subclassed from QStyledItemDelegate. I create a QSlider to edit the progress.

The problem is, that each editor widget has to draw its own background, and has to overdraw the old one. So I set the setAutofill property of the slider to true, and get the result showed in the screenshot (background is one solid colour, but I want it to match the rest of the row).

If I don't set the autofill property the background is not drawn at all, and I can see the progressbar drawn under the slider.

I tried to intercept paint events to the slider and draw the background myself using QStyle()::drawPrimitive( QStyle::PE_PanelItemViewItem, &option, painter ), but this doesn't result in good results because I do not have the correct QStyleOptionViewItemV4 object (selection state etc. is not correct, because this is usually set by the view IMHO).

So how can I draw the correct background for the slider without having to filter tons of events to find out the correct state of the item.

Thanks in advance,
Thomas

jpn
29th March 2008, 22:21
Try testing QStyleOption::state for QStyle::State_Editing.

chiefaua
29th March 2008, 23:06
I've tried to check for this state, but apparently this state is never set.
I also tried to not to paint the progress bar (but the background) when the item is for example selected, and then the editor is displayed correctly (but no progress bar is displayed when the user selects a row...).

So I think the problem is that views don't initialize the provided option appropriately. I could however store the QModelIndex of the currently edited item (in createEditor), and then test for that in the paint method. But this would obviously be a hack, and I would like to avoid that.

Thomas

jpn
30th March 2008, 11:46
You mustn't store QModelIndexes but you would have to store expensive QPersistentModelIndexes. Anyway, instead of storing edited model index to the delegate, I'd make the delegate aware of the view (parent) and check if QAbstractItemView::state() corresponds to QAbstractItemView::EditingState and QAbstractItemView::currentIndex() corresponds to the passed QModelIndex parameter.

PS. It seems that QListView is the only view which actually sets QStyle::State_Editing.

chiefaua
30th March 2008, 16:51
I tried to check the views state, but QAbstractItemView::state() and the QAbsractItemView::State enum are both protected. So I can't access them from within the delegate.

As only the QListView sets QStyle::State_Editing correctly, could one assume that that's a Qt bug? I mean before Qt 4.4 where QStyledItemDelegate became the default it was no problem to draw the background from within the editing widget, as the background was only one solid colour. But now, with the new delegate, the background has gradients etc. drawn on it, and the QStyle::State_Editing flag would be very useful to prevent delegates from drawing the actual content while in editing mode.

If you also think that that's a Qt bug I will submit a new bug, but I really think that it should not be as hard to draw a standard background while in editing mode.

jpn
30th March 2008, 16:53
Yeah, I agree. QStyle::State_Editing should be set by all views.