QTableView blank rows when hiding elements
-
My QTableView has a few hundred elements. However, I only want some of them shown when a certain checkbox is selected. So, I have a method that hides and shows certain rows, based on said checkboxes. However, even though I only end seeing about 10 elements, I see hundreds of empty rows. The scrollbar to the right is very small due to this. Another problem is, when I scroll to the very bottom, I get an exception:
ASSERT failure in QBitArray::QBitArray: "Size must be greater than or equal to 0"
I'm not sure what caused this, since I have no code anywhere that touches the scrolling, not even close. All I'm doing is populating the QTableView, then hiding/showing based on the boxes. Note that checking the "everything" checkbox, supposed to show everything, still contains blank lines at the end, so it might not be due to hiding. Here are some relevant lines creating and populating as well as hiding the rows.
model = new QStandardItemModel(0, 6); model -> setColumnCount(7); ui->boxTableView->setItemDelegate(new FormattingStyledItemDelegate(this)); ui->boxTableView->setModel(model); ui -> boxTableView -> horizontalHeader() -> setSectionResizeMode(QHeaderView::Stretch); model -> setHorizontalHeaderLabels(QStringList() << "1" << "2" << "3" << "4" << "5" << "6" << "7"); foreach(Item i, items){ model -> appendRow(QList < QStandardItem * > () << new QStandardItem(item.one) << new QStandardItem(item.two) << new QStandardItem(item.three) << new QStandardItem(item.four) << new QStandardItem(item.five) << new QStandardItem(item.six) << new QStandardItem(item.seven)); }
Then the hiding:
//Reset everything for (int i = 0; i < modelSize; i++) { ui->boxTableView->hideRow(i); } //One for each checkbox for (int i = 0; i < modelSize ; i++) { if(ui->checkBoxOne->isChecked()){ ui->boxTableView->showRow(i); } } //...
Screenshots:
Thanks in advance.
-
Hi,
What happens if you do not use your delegate ?
-
Which version of Qt is it ?
Can you provide a minimal compilable example that shows that issue ? -
@SGaist Qt 6.0.2 using MSVC 2019
Of course!
Here it is:
void MyClass::Init() { QStandardItemModel *model; QFutureWatcher<void> watcher; model = new QStandardItemModel(0, 1); model -> setColumnCount(1); ui->boxTableView->setModel(model); model -> setHorizontalHeaderLabels(QStringList() << "ex"); connect( & watcher, & QFutureWatcher < void > ::finished, [ = ]() { ui->boxTableView->setHidden(false); }); QFuture < void > future = QtConcurrent::run([ = ]() { for (int i = 0; i < 30 ; i++) { model -> appendRow(QList < QStandardItem * > () << new QStandardItem("testdata")); } }); watcher.setFuture(future); }
I basically removed everything, but it was adding the QFuture/Watcher that made it act like this. This reproduces both bugs, the extra lines and the crash when scrolling. The crash doesn't occur in Release, but the line bug does.
-
QtConcurrent::run([ = ]() { for (int i = 0; i < 30 ; i++) { model -> appendRow(QList < QStandardItem * > () << new QStandardItem("testdata")); }
This is a race condition, the model belongs to the main thread, you can't just edit it in a secondary thread like it's nothing.