Как заставить QAbstractItemView пересчитать элементы sizeHints

У меня есть QListView и QTabWidget внутри QSplitter. QListView использует пользовательскую модель и пользовательские делегаты. В делегате я переопределил методы paint и sizeHint. Но когда я изменяю размер представления - высота элементов не пересчитывается. Как я могу это исправить? Образцы изображений:

Перед изменением размераПосле изменения размера

В гугле я обнаружил, что можно вывести layoutChanged из модели, но я хочу, чтобы обновлялся только текущий вид, потому что содержимое модели не меняется.

Код делегата:

void ChatItemDelegate::paint( QPainter *painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const
{
    painter->save();

    ChatItem *item = static_cast< ChatItem * >( index.internalPointer() );
    QTextDocument doc;

    doc.setHtml( item->htmlText() );
    doc.setTextWidth( option.rect.width() );

    QRect clip( 0, 0, option.rect.width(), option.rect.height() );
    painter->translate( option.rect.topLeft() );

    QColor bgColor = index.row() % 2 ? QColor( 255, 0, 0, 40 ) : QColor( 0, 255, 0, 40 );
    painter->fillRect( clip, bgColor );
    doc.drawContents( painter, clip );

    qDebug() << "paint: " << option.rect.width() << " idx: " << index.row();

    painter->restore();
}

QSize ChatItemDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const
{
    ChatItem *item = static_cast< ChatItem * >( index.internalPointer() );
    QTextDocument doc;

    doc.setHtml( item->htmlText() );
    doc.setTextWidth( option.rect.width() );

    qDebug() << "hint:  " << option.rect.width() << " idx: " << index.row();

    return doc.size().toSize();
}

Подобный вопрос

5 ответов

После поиска исходного кода Qt я обнаружил, что функция scheduleDelayedItemsLayout() решает проблему на моей стороне.

Испытывает ту же проблему в ноябре 2017 года...

Единственный способ, который я нашел, чтобы решить это, это этот уродливый хак:

   QSize size = listView->viewport()->size();
   size.setHeight(size.height()+1);
   listView->viewport()->resize(size);

   size.setHeight(size.height()-1);
   listView->viewport()->resize(size);

Он вызывает изменение размера списка, которое само обновляет размеры строк.

Это немного догадка, но помогает ли настройка режима изменения размера вашего QListView?

listView->setResizeMode( QListView::Adjust );

Как насчет QAbstractItemView::doItemsLayout()

https://code.woboq.org/qt5/qtbase/src/widgets/itemviews/qabstractitemview.cpp.html#_ZN17QAbstractItemView13doItemsLayoutEv

Я понятия не имею, почему эта функция существует в Qt Sources как общедоступный API, но она не была задокументирована, но, похоже, она отлично работает для меня.

Ни одно из других решений не сработало для меня, но это сработало:

      listView->setViewMode(QListView::IconMode);
listView->setViewMode(QListView::ListMode);
Другие вопросы по тегам