问题描述:区分 QTableWidget 类的 clear() 和 clearContents() 的用法,以及可能由于这两个方法使用不当导致程序崩溃的原因分析
Qt 官方文档对 QTableWidget 类的 clear() 方法描述如下:
[slot] void QTableWidget::clear()
Removes all items in the view. This will also remove all selections and headers. If you don't want to remove the headers, use QTableWidget::clearContents(). The table dimensions stay the same.
翻译过来就是,clear() 函数会删除表格中的所有单元格,也会删除选中的部分和表头,但不会改变原先设置的行数和列数
Qt 官方文档对 QTableWidget 类的 clearContents() 方法描述如下:
[slot] void QTableWidget::clearContents()
Removes all items not in the headers from the view. This will also remove all selections. The table dimensions stay the same.
翻译过来就是,clearContents() 函数会删除表格中的所有单元格,也会删除选中的部分,但不会删除表头,也不会改变原先设置的行数和列数
clear() 和 clearContents() 的相同点在于都会删除表格中的所有单元格,也会删除选中的部分,并且保持原先设置的行数和列数不变,区别在于 clear() 会删除表头,clearContents() 不会删除表头
在程序中如果对 clear() 和 clearContents() 方法调用不当,将会导致程序崩溃,究其原因在于这两个方法删除了表格中的所有单元格,导致了空指针,如果对空指针进行操作,将会使得程序崩溃
void clearTable()
{
table->clear(); // 或者 table->clearContents()
}
void setTableText(QVector<QStringList> textSL)
{
for(int i=0; i<textSL.size(); i++)
{
QStringList sl = textSL.at(i);
for(int j=0; j<sl.size(); j++)
{
table->item(i,j)->setText(sl.at(j));
}
}
}
先下结论,上述代码会导致程序崩溃!!!
上述代码逻辑我们在程序中经常使用,clearTable() 函数清空表格内容,setTableText() 为表格所有单元格再赋新值。程序崩溃的原因在于 clear() 和 clearContents() 删除了表格中的所有单元格,导致了 table->item(i,j) 空指针,再调用 setText() 函数导致程序崩溃
为了解决上述空指针问题,需对代码进行修改,即清空内容的时候不要删除单元格,或者在调用单元格函数的时候先判断指针是否为空,如果为空,则为该单元格创建一个 QTableWidgetItem
方法1:清空内容的时候不要删除单元格
void clearTable()
{
for(int i=0; i<table->rowCount(); i++)
{
for(int j=0; j<table->columnCount(); j++)
{
table->item(i,j)->setText("");
}
}
}
void setTableText(QVector<QStringList> textSL)
{
for(int i=0; i<textSL.size(); i++)
{
QStringList sl = textSL.at(i);
for(int j=0; j<sl.size(); j++)
{
table->item(i,j)->setText(sl.at(j));
}
}
}
方法2:在调用单元格函数的时候先判断指针是否为空,如果为空,则为该单元格创建一个 QTableWidgetItem
void clearTable()
{
table->clearContents();
}
void setTableText(QVector<QStringList> textSL)
{
for(int i=0; i<textSL.size(); i++)
{
QStringList sl = textSL.at(i);
for(int j=0; j<sl.size(); j++)
{
if(!table->item(i,j))
{
QTableWidgetItem * item = new QTableWidgetItem;
table->setItem(i,j,item);
}
table->item(i,j)->setText(sl.at(j));
}
}
}