i'm having difficulties implementing custom widget rendering in a QListView
.
I currently have a QListView
displaying my custom model called PlayQueue
based on QAbstractListModel
.
This is working fine with simple text, but now I would like to display a custom widget for each element.
So I subclassed a QStyledItemDelegate
to implement the paint
method like this:
void QueueableDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
{
if (option.state & QStyle::State_Selected)
painter->fillRect(option.rect, option.palette.highlight());
QWidget *widget = new QPushButton("bonjour");
widget->render(painter);
}
The selection background is properly rendered but no widget is displayed. I tried with simple QPainter
commands like in Qt examples, and this is working fine:
void QueueableDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
{
if (option.state & QStyle::State_Selected)
painter->fillRect(option.rect, option.palette.highlight());
if (option.state & QStyle::State_Selected)
painter->setPen(option.palette.highlightedText().color());
painter->setFont(QFont("Arial", 10));
painter->drawText(option.rect, Qt::AlignCenter, "Custom drawing");
}
So I tried some changes like:
- Changing
QStyledItemDelegate
toQItemDelegate
- Adding
painter->save()
andpainter->restore()
around rendering - Setting the widget geometry to the available size
But i'm a bit stuck now, i searched for a while on the internet, but can't find any example doing what i want, they all talk about editing widget (which is a lot easier) or custom drawn control (predefined ones, like progress bars). But here I really need a custom widget I created, containing some layout, labels & pixmaps. Thanks for your help!
I'm using Qt 4.7.3 for GCC on Ubuntu 11.04.
Just to complete the whole picture: further one can find the code to manage the QWidget as QListView item using delegates.
I finally found out how to make it work within the subclass of QStyledItemDelegate using its paint(...) method.
It seems more effective for performance than previous solution, but this statement one needs to verify =) by investigation what does setIndexWidget() do with created QWidget.
So finally, here is the code:
.....
.....
Ok I finally figured out how to do what I wanted. Here is what I did:
QListView::setIndexWidget()
in thedata()
method of my model to set the widgetQListView::indexWidget()
Qt::SizeHintRole
role to return the widget's size hintQt::DisplayRole
roleThis way I have my custom widgets displayed in the QListView, and they are properly lazy-loaded (that's why i used the model/view pattern). But I don't see how can I unload them when not beeing displayed, well that's another problem.
Here is an example for you. It seems that you need to use QStylePainter but this is just for drawing as far as I understand it does not act like a real button.