现象
结论
-
clearContents()
会清除表格中的所有单元格内容,包括释放
之前创建的QTableWidgetItem
和通过setCellWidget()
设置的QWidget
对象,但是不指向nullptr
并且是延时释放QWidget
的而QTableWidgetItem
立即释放; - 使用
setItem
方法将一个QTableWidgetItem
对象设置为表格中的一个单元格后,该对象的位置(即所在行的索引)不会改变。这意味着,如果之后将该对象设置为其他单元格,它的位置将保持不变;
原因:QTableWidgetItem 对象是动态地与表格的行和列关联的。当使用 setItem 方法将一个 QTableWidgetItem 对象设置为某个单元格时,该对象的位置将保持不变,因为它是与该单元格关联的
- 而使用
setCellWidget
方法将一个QWidget
对象设置为表格中的一个单元格时,该对象的位置可能会改变;
原因: QWidget 对象不是直接与表格的行和列关联的,而是与 QTableWidget 对象本身关联的。
- 总的来说:
QTableWidgetItem 对象与表格的行和列关联,而 QWidget 对象与整个表格本身关联。因此,当更改单元格中的 QTableWidgetItem 对象时,该对象的位置将保持不变;而当更改单元格中的 QWidget 对象时,该对象的位置将根据设置的单元格位置而改变。
- 官方开发文档
代码验证clearContents() 会释放QTableWidgetItem 和QWidget 对象,但是不指向nullptr
memorytable.h
#ifndef MEMORYTABLE_H
#define MEMORYTABLE_H
#include <QWidget>
#include <QCheckBox>
#include <QTableWidgetItem>
#include <QDebug>
QT_BEGIN_NAMESPACE
namespace Ui { class MemoryTable; }
QT_END_NAMESPACE
class MemoryTable : public QWidget
{
Q_OBJECT
public:
MemoryTable(QWidget *parent = nullptr);
~MemoryTable();
private slots:
void on_btnAdd_clicked();
void on_btnClear_clicked();
private:
Ui::MemoryTable *ui;
QCheckBox*m_pQCheckBox=nullptr;
QTableWidgetItem *m_pItem=nullptr;
};
#endif // MEMORYTABLE_H
memorytable.cpp
#include "memorytable.h"
#include "ui_memorytable.h"
#pragma execution_character_set("utf-8")
MemoryTable::MemoryTable(QWidget *parent)
: QWidget(parent)
, ui(new Ui::MemoryTable)
{
ui->setupUi(this);
this->setWindowFlag(Qt::WindowStaysOnTopHint);
ui->tableWidget->horizontalHeader()->setSectionResizeMode(
QHeaderView::Stretch);
}
MemoryTable::~MemoryTable()
{
delete ui;
}
void MemoryTable::on_btnAdd_clicked()
{
if(m_pQCheckBox==nullptr){
m_pQCheckBox=new QCheckBox();
m_pQCheckBox->setCheckState(Qt::Checked);
}
if(m_pItem==nullptr){
m_pItem=new QTableWidgetItem();
m_pItem->setText("QTableWidgetItem 不为空");
}
auto state =m_pQCheckBox->checkState();
QString text =m_pItem->text();
int rowCount=ui->tableWidget->rowCount();
ui->tableWidget->insertRow(rowCount);
ui->tableWidget->setCellWidget(rowCount,0,m_pQCheckBox);
ui->tableWidget->setItem(rowCount,1,m_pItem);
int curRow =m_pItem->row(); //curRow 一直
}
void MemoryTable::on_btnClear_clicked()
{
ui->tableWidget->clearContents();
//ui->tableWidget->setRowCount(0);
}
断点情况
验证clearContents()是延时释放QWidget 的而QTableWidgetItem 立即释放
- 直接在
clearContents()
后加上delete m_pQCheckBox不报错(重复删除(delete)同一个指针是不允许的) - 而 delete m_pItem或者访问m_pItem就会崩溃;(打断点/qDebug()就知道崩溃点了)
void MemoryTable::on_btnClear_clicked()
{
ui->tableWidget->clearContents();
auto state =m_pQCheckBox->checkState(); //不会崩溃
qDebug()<<"state"<<state;
delete m_pQCheckBox; //不会崩溃
m_pQCheckBox = nullptr;
QString text =m_pItem->text(); //会崩溃
//ui->tableWidget->setRowCount(0);
}