Details
-
Bug
-
Resolution: Done
-
P1: Critical
-
None
-
5.5.1
-
None
-
Windows 10
Description
When inserting rows at the beginning of an item model of a QTableView that has hidden rows, the following assertion is being violated:
Qt5Cored.dll
Module: 5.5.1
File: global\qglobal.cpp
Line: 2966
ASSERT: "uint(i) < uint(size())" in file d:\depot\thirdparty\redistsdks\qt\5.5.1\src\qtbase\src\corelib\tools\qbitarray.h, line 122
This can be reproduced using the following code:
#include <QtGui> #include <QApplication> #include <QTableView> #include <QAbstractItemModel> class MyItemModel : public QAbstractItemModel { public: void insertRowAtBeginning() { Q_EMIT layoutAboutToBeChanged(); //beginInsertRows(QModelIndex(), 0, 0); m_displayNames.insert(0, QString("Item %1").arg(m_displayNames.count())); // Rows are always inserted at the beginning, so move all others. Q_FOREACH(QModelIndex persIndex, persistentIndexList()) { // The vertical header view will have a persistent index stored here on the second call to insertRowAtBeginning. changePersistentIndex(persIndex, index(persIndex.row() + 1, persIndex.column(), persIndex.parent())); } Q_EMIT layoutChanged(); //endInsertRows(); } virtual QVariant data(const QModelIndex &index, int role) const { if (role == Qt::DisplayRole) return m_displayNames[index.row()]; return QVariant(); } virtual QModelIndex index(int row, int column, const QModelIndex &parent) const { return createIndex(row, column); } virtual QModelIndex parent(const QModelIndex &child) const { return QModelIndex(); } virtual int rowCount(const QModelIndex &parent) const { return m_displayNames.count(); } virtual int columnCount(const QModelIndex &parent) const { return 1; } private: QStringList m_displayNames; }; int main(int argc, char **argv) { QApplication app(argc, argv); QTableView* tableView = new QTableView(); MyItemModel* itemModel = new MyItemModel(); tableView->setModel(itemModel); tableView->show(); itemModel->insertRowAtBeginning(); tableView->setRowHidden(0, true); itemModel->insertRowAtBeginning(); // the hidden row is now moved to row 1. return app.exec(); }
This only happens if the item model notifies the view using the layoutChanged signals (instead of rowsInserted signals), which should be working as well if I'm correct to assume that QHeaderViewPrivate::_q_layoutChanged() is supposed to handle section count changes.
Modifying QHeaderViewPrivate::_q_layoutChanged() like this should fix the problem:
void QHeaderViewPrivate::_q_layoutChanged() { Q_Q(QHeaderView); viewport->update(); if (modelSectionCount() != sectionCount()) { q->initializeSections(); } if (persistentHiddenSections.isEmpty() || modelIsEmpty()) { persistentHiddenSections.clear(); return; } ...
Attachments
Issue Links
- is duplicated by
-
QTBUG-24922 QHeaderView::initializeSections unhides hidden columns if the section count is changed
- Closed
For Gerrit Dashboard: QTBUG-53221 | ||||||
---|---|---|---|---|---|---|
# | Subject | Branch | Project | Status | CR | V |
180250,2 | QHeaderView: Simplify and fix layoutChange handling | 5.8 | qt/qtbase | Status: ABANDONED | +1 | 0 |
210447,2 | QHeaderView: Do not assert when shifting a hidden row on layoutChanged | 5.9 | qt/qtbase | Status: ABANDONED | 0 | 0 |
211791,3 | QHeaderView: Simplify and fix layoutChange handling | 5.9 | qt/qtbase | Status: MERGED | +2 | 0 |