探索QTableWidget对单元格(QWidget/QTableWidgetItem)的内存管理[clearContents()]

简介: 1.clearContents() 会清除表格中的所有单元格内容,包括释放之前创建的QTableWidgetItem和通过 setCellWidget() 设置的 QWidget 对象,但是不指向nullptr并且是延时释放QWidget 的而QTableWidgetItem 立即释放;2.使用 setItem 方法将一个 QTableWidgetItem 对象设置为表格中的一个单元格后,该对象的位置(即所在行的索引)不会改变。这意味着,如果之后将该对象设置为其他单元格,它的位置将保持不变;3.而使用 setCellWidget 方法将一个QWidget对象设置单元格时,位置可能会改变

现象

memory.gif

结论

  1. clearContents() 会清除表格中的所有单元格内容,包括释放之前创建的 QTableWidgetItem 和通过 setCellWidget() 设置的 QWidget 对象,但是不指向nullptr并且是延时释放QWidget 的而QTableWidgetItem 立即释放;
  2. 使用 setItem 方法将一个 QTableWidgetItem 对象设置为表格中的一个单元格后,该对象的位置(即所在行的索引)不会改变。这意味着,如果之后将该对象设置为其他单元格,它的位置将保持不变;
原因:QTableWidgetItem 对象是动态地与表格的行和列关联的。当使用 setItem 方法将一个 QTableWidgetItem 对象设置为某个单元格时,该对象的位置将保持不变,因为它是与该单元格关联的
  1. 而使用 setCellWidget 方法将一个 QWidget 对象设置为表格中的一个单元格时,该对象的位置可能会改变;
原因: QWidget 对象不是直接与表格的行和列关联的,而是与 QTableWidget 对象本身关联的。
  • 总的来说:

QTableWidgetItem 对象与表格的行和列关联,而 QWidget 对象与整个表格本身关联。因此,当更改单元格中的 QTableWidgetItem 对象时,该对象的位置将保持不变;而当更改单元格中的 QWidget 对象时,该对象的位置将根据设置的单元格位置而改变。

  • 官方开发文档

image.png

代码验证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);
}

断点情况

image.png

验证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);
}
相关文章
|
2月前
|
监控 开发者 UED
QLineEdit:textChanged、textedited区别
总之,理解 `textChanged`与 `textEdited`之间的细微差别,可以帮助开发者更加精准地控制用户界面的响应逻辑,提升应用程序的互动性和效率。
114 3
|
4月前
Qt绘图之QWidget
Qt绘图之QWidget
89 1
|
7月前
|
XML 设计模式 JSON
QT 项目视图(QListView&QTreeView&QTableView)和项目部件(QListWidget&QTreeWidget&QTableWidget)详解-1
QT 项目视图(QListView&QTreeView&QTableView)和项目部件(QListWidget&QTreeWidget&QTableWidget)详解
|
7月前
|
数据库 开发者 Windows
QT 项目视图(QListView&QTreeView&QTableView)和项目部件(QListWidget&QTreeWidget&QTableWidget)详解-2
QT 项目视图(QListView&QTreeView&QTableView)和项目部件(QListWidget&QTreeWidget&QTableWidget)详解
|
6月前
QT布局管理器
QT布局管理器
|
7月前
【qt】QTableWidget 表格组件3
【qt】QTableWidget 表格组件
82 0
|
7月前
【qt】QTableWidget 表格组件1
【qt】QTableWidget 表格组件
51 0
|
7月前
【qt】QTableWidget 表格组件2
【qt】QTableWidget 表格组件
69 0
|
C语言
QT QtableView操作详解
本文实现了使用QtableView控件来显示数据,数据源使用txt文本作为数据源,使用了QStandardItemModel作为数据模型来实现了对TableView空间的初始化,和对txt数据源的增删改查功能。
573 0
QT QtableView操作详解