PDA

View Full Version : Paint in Custom Delegate



Nightfox
3rd October 2010, 22:09
I'm currently looking to display the text of the first column in a treeview in such way that the text takes up the space of both column one and two - sort of like a merged cell in MS Excel. The approach must only apply for item in the tree that have children branches underneath.

I've subclass the QItemDelegate in the following way


class PostDelegate : public QItemDelegate
{
Q_OBJECT

public:
PostDelegate(QObject *parent=0) : QItemDelegate(parent){}
~PostDelegate(){}
void paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const
{
if(index.model()->hasChildren(index) && index.column() < 2 ) { //GroupProxyRecord
QItemDelegate::drawBackground(painter , option , index) ; //draw bagground first
QModelIndex idx = index;
if(index.column() == 1) { //redirect to column 0
idx = index.sibling(index.row() , 0) ;
}
QStyleOptionViewItem opt ;
QSize s = sizeHint(opt , idx) ;
QString value = idx.data().toString() ;
QRectF rectF = painter->boundingRect ( opt.rect , Qt::AlignLeft, value ) ;
painter->drawText(rectF, value );

} else {
QItemDelegate::paint(painter , option , index) ;
}

}

QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const
{
return QItemDelegate::sizeHint(option, index);
}

};


Now, I'm almost there but I can't seem to calculate the rectangle that covers index column one and two in order to calculate the right QRect for the painter.

If you look at the attached picture the merge cell paint must only apply to row 0,1,5 and 9.

My question is: How can I retrieve/calculate the rect associated with a given QModelIndex?

5267

Any suggestions out there?

Nightfox
6th October 2010, 17:48
What's going on guys? No Delegate / Paint experts out there ?

wysota
7th October 2010, 00:58
If it is just about getting the size then you can ask the horizontal header for the width of an appropriate section. But honestly I don't think that what you are doing is a good approach. I would rather lean towards reimplementing QTreeView::drawRow() or QAbstractItemView::visualRect() to physically make the item span across two columns instead of emulating such a look.

Nightfox
7th October 2010, 20:20
Hi wysota, thank you for your reply.
The reason I'm subclassing the QItemDelegate is that it's far simpler to subclass than the QTreeView . The second reason is that the QItemDelegate must work on both treeviews and tableview without having to subclass every time. Plus I may loose or I need to consider built in functionality in the treeview / tableview like the alternating row color. In that respect it's far easier to subclass the QItemDelegate.

What I've started to do is the following which I think is kind of what you're suggesting, right?;


QAbstractItemView *view = qobject_cast<QAbstractItemView *>(parent() );
if(!view) return;
QRect rec = view->visualRect(idx);

wysota
7th October 2010, 20:54
In that respect it's far easier to subclass the QItemDelegate.
It's also far easier to break the design. I.e. if someone reorders columns in the table view.

If you reimplement visualRect() or drawRow() you will not lose alternating rows. It's more work if you want to implement drawRow() without losing what it is doing though. With visualRect() you should be safe.