0

I have a QListView where I set the model to a custom QAbstractItemModel, as well as a custom QStyledItemDelegate.

ui->listView->setModel(model);
ui->listView->setItemDelegate(new Delegate(ui->listView));

I followed this great answer on how to set the delegate up properly, so I overloaded paint() and sizeHint():

void
Delegate::paint(QPainter *painter,
                const QStyleOptionViewItem &option,
                const QModelIndex &index) const
{
    std::cout << __func__ << ": " << option.rect.width() << "x" << option.rect.height() << std::endl;

    QStyleOptionViewItem opt(option);
    initStyleOption(&opt, index);

    painter->save();
    // draw background of option.rect and some text
    painter->restore();
}
QSize
Delegate::sizeHint(const QStyleOptionViewItem &option,
                   const QModelIndex &index) const
{
    std::cout << __func__ << ": " << option.rect.width() << "x" << option.rect.height() << std::endl;

    return QSize(option.rect.width(), 100);
}

When I add an item to my model, it is properly propagated to the QListView and the delegate prints the following:

sizeHint: 1551x87
sizeHint: 0x0
paint: 0x0

Every new item I add is then drawn on top of the previous items, and the backgrounds aren't drawn, since option.rect is 0x0.

I've tried changing a bunch of its size-related properties of my QListView to no avail.

So why do the passed QStyleOptionViewItem have a rect of 0x0, or generally, where do the QStyleOptionViewItem get its properties from? Qt's paint documentation and sizeHint documentation doesn't seem very clear on this.

Thanks in advance!

seht97
  • 67
  • 6
  • sizeHint() is there so that you tell the size you need, option.rect will then get this value for the painting / resizing of the cell – chehrlic Jan 20 '23 at 11:47
  • @chehrlic I've set `sizeHint` to return `QSize(option.rect.width(), 100)`, so shouldn't the height in `paint` at least be 100? – seht97 Jan 20 '23 at 14:01
  • I have not read Qt's code for that part but if your `QSize` is not valid (`width == 0` => `isValid() == false`), I am not surprised you are getting this behavior. – Atmo Jan 20 '23 at 14:08
  • Returning hardcoded `QSize(100, 100)` in `sizeHint` does not change the behaviour (ie `paint` does not receive `option.rect` of size `100x100`. – seht97 Jan 20 '23 at 14:16

1 Answers1

0

The issue was found in the model instead (columnCount() being calculated wrong). So if you encounter the same issue, try checking the model implementation.

By using the default QListView delegate, nothing was printed, even though I use Qt::DisplayRole. This way, the issue was isolated to be in the model, and not the view nor the delegate.

seht97
  • 67
  • 6