In the proprietary code base I'm currently working with, there is a custom list view (derived form QListView
).
Currently it has an issue when lots of items (>10000) make the main thread freeze. Every item in the view is a custom widget designed in QtDesigner.
To render every row, we use setIndexWidget
, which is called on QAbstractItemModel::rowsInserted
signal. For every inserted row, from first
to last
custom widget is set for every index.
I tried to port this code to use QStyledItemDelegate
, because disconnecting item widget from actual model seems to solve slow rendering.
Qt5 in that case can render items in view lazily, on demand. We will not need to create every widget for view before displaying the list.
I achieved initial results, using a class which is derived from QStyledItemDelegate
. I create a list item widget in constructor and then override paint event like this.
void paint(QPainter *painter, const QStyleOptionViewItem &option,const QModelIndex &index) const override {
auto baseWid = getBaseWidget(); // Get's list item widget pointer
setSubEditorData(baseWid,index); // Set's it's state to display current item
baseWid->resize(option.rect.size());
QPixmap pixmap(option.rect.size());
baseWid->render(&pixmap);
painter->drawPixmap(option.rect, pixmap);
}
This is sufficient for static content, but my widget has checkboxes and can be selected.
I don't really understand how to make it interactive, while preserving benefits delegates provide (rendering on demand and so on).
My question is how to make delegate handle user events? Like mouse clicks, selection changes.
Qt5 examples covering delegates are too simple, I don't understand how to draw with delegate a custom widget.