如何修复QTableWidget setText / setCellWidget导致加载QSettings时崩溃

时间:2019-02-06 23:52:18

标签: qt qtablewidget qtablewidgetitem qsettings

您好,我使用的是git clone https://github.com/red-swan/fake-sqlite-problem.git,并且本质上具有使第一列允许表动态增长/收缩的代码。填充的最后一行的第一个单元格将带有一个加号按钮,以添加可以编辑的新行,减号按钮将删除其对应按钮的行。例如,如果我单击“加号”按钮5次,它将位于第6行,而前5行将全部带有“减号”按钮以删除其行。如果单元格的行上有减号按钮,则该行隐含可编辑,否则就不可编辑。但是,我允许表具有默认的行数,例如,即使从技术上讲它是“空”的,也不允许它在视觉上缩小到小于5。要编辑该行,您需要单击加号按钮,该按钮将检查是否需要插入新行,例如,如果我们位于5行且基本行大小为5,则需要新行并填充新行的每一列的索引。

该表的主要原因是将表的信息读写到QTableWidget,并且能够将过去导出的信息导入到相同的单元格中,并且实质上恢复了表的状态。但是,当从QSettings读取数据时,所有信息正确填充了所有单元格后,该表将崩溃,并且由于调试器将冻结GUI,并且可以直观地看到和{{1} }段隔离前到达QSettings数组循环的距离。

现在,当我手动执行所有操作(例如单击加号按钮)时,一切都很好,程序将按预期执行。

qDebug()

但是,这都是字节码,我实际上无法使用调试器检查哪一行使任何跟踪中的代码崩溃。我不了解的是,手动单击加号按钮的相同过程已经完成(我将加号按钮的click事件连接到QSettings函数),并且当我以编程方式从//newRowCount is assumed to be the amount of rows with Minus Buttons currently, only creates a new row if the table needs to expand void TableTest::enableNewRow(){ newRowCount++; if(newRowCount > table->rowCount()){ table->insertRow(table->rowCount()); for(int i = 0; i < table->columnSize(); ++i){ QTableWidgetItem* item = new QTableWidgetItem; item->setFlags(item->flags() ^ Qt::ItemisEditable); table->setItem(newRowCount, i, item); //Code to set the previous column's item (newRowCount--) to have an Qt::ItemisEditable flag set to true ... } } //Some button setup to make Plus button and create a new Minus button connect and do their jobs and move the Plus button down into the newly inserted row ... } void MainWindow::importFile(){ int settingRows = settings->beginReadArray("Groups"); for(int i = 0; i < settingRows; ++i){ settings->setArrayIndex(i); //Will only add a new row if needed, check inside above function and all row items will be allocated if made table->enableRow(); for(int j = 1; j < table->columnCount(); ++j){ table->item(i, j)->setText("testing"); } } } And the program crashes with the following stack trace: 1 QWidget::show() 2 QAbstractItemView::updateEditorGeometries() 3 QAbstractItemView::updateGeometries() 4 QTableView::updateGeometries() 5 QTableView::timerEvent(QTimerEvent *) 6 QObject::event(QEvent *) 7 QWidget::event(QEvent *) 8 QFrame::event(QEvent* ) 9 QAbstractScrollArea::event(QEvent* ) 10 QAbstractItemView::event(QEvent* ) 11-21 ... Not useful information about any of the code 22 QCoreApplication::exec() 23 main 中的enableRow()循环在遍历所有项目后将崩溃。

注意事项:将表的基本大小设置为我正在读取的QSettings数组的大小(即,如果我想要10行,只需在设置项目文本之前先设置10行即可正常工作)但是,我希望创建时表的基本大小为5。似乎一旦循环超出了我从构造函数指定的行数,则程序将崩溃,但不是崩溃,而是索引6,但是仅在它完全遍历表之后。它不会在enableRow()QSettings之类的任何行上崩溃。我有点困惑,想知道对于堆栈跟踪行5上的importFile()来说,表的填充速度是否太快了,所以我在循环中所做的与正常操作表时没有什么不同。

1 个答案:

答案 0 :(得分:0)

事实证明,错误是我将QTableWIdgetItem设置的时间比原先设置的早了一行。我不确定为什么表可以在崩溃前进行迭代直到QSettings循环结束,但这实际上就是错误。我不太确定为什么堆栈跟踪如此神秘。

在我的enableRow()函数中,我实际上是从内存中发布了正确的逻辑,该逻辑在我的代码逻辑中与之前的行值相差1个索引。为什么在通常使用带有与import()相同的功能的按钮的按钮时代码没有崩溃,这似乎使我感到困惑,这也许是行为未定义的情况。