本博客对应的QT版本:Qt 5.12.2
1 使用setCellWidget添加的控件元素,如何释放
在本人的工程中,QTableWidget的表格分为多行多列,且行数是动态变化的。
表格中的每一格都是new一个控件(QCombox或者QSpinBox)。
采用以下方式加入到表格的第i行第j列中(i,j从0开始):
QSpinBox* sb = new QSpinBox();
theTableWidget->setCellWidget(i, j, sb);
当表格调用 removeCellWidget(0,0)、 removeRow(0)、 clear方法之后,原本new出来的控件对象(比如sb )是否被正常释放呢;
测试如下:
void mainWindow::on_pushButton_clicked()
{
static int lable = 0;
static void* addr = 0; //保存new出来的sb内存地址
if(lable == 0 )//只new一次
{
lable = 1;
QSpinBox* sb = new QSpinBox();
addr = (void*)sb;
sb->setRange(0,1000);
sb->setValue(100);
theTableWidget->setCellWidget(0, 0, sb);
theTableWidget->removeCellWidget(0,0); //这一句不能释放sb
//theTableWidget->removeRow(0);//这一句也不能释放sb
//delete sb;
}
else //访问new出的地址
{
//访问之前new出的地址
QSpinBox* sb_2 = (QSpinBox*)addr;
//之前的地址还能访问,说明没有被释放。 若程序奔溃,则之前new出的对象被释放
int v = sb_2->value();
int bbb = v;
}
}
很遗憾,多次点击按钮后程序并不奔溃,且sb_2->value()均为100。可以得出结论:实测表明,removeCellWidget(0,0)、 removeRow(0)、 clear方法之后,原本new出来的控件对象(比如sb )并不能被自动释放。需要人为释放,否则会造成内存泄漏。
想通过QT的对象树内存管理技术来实现自动释放,但是在现有框架下,难以对sb ->setParent(传参)函数进行传参。本人的初始想法是将表格的某一行作为sb的父类,那么在删除这一行时,sb作为子控件会被自动释放。 但是对于QTableWidget,如何获取它的某一行的指针(元素)??? 若有知道如何获取的读者请留言交流,谢谢!!
QTableWidget的item(i,j)、itemAt方法都测试过了,不起作用!
所以,在表格的每一小格new出新元素后,需要以某种形式存储起来,在删除、清除该小格时,要手动delete释放!!!以免造成内存泄漏。