Qt关于列表删除操作的详细解析
前言
在使用QList时,需要进行删除某一项的操作,发现QList提供了两个移除的方法,一个是removeAt(),一个是takeAt()。我创建的是一个存放指针变量的QList,需要实现两个功能,一个是移除并销毁item,一个是移除但是不销毁item。在选择这两个方法时就产生了疑问。于是查阅了官方帮助和网上资料做对比,总结一下这两个方法的区别。
官方解释
- removeAt(i): 删除索引位置i的项。i必须是列表中有效的索引位置(即0 <= i < size())。
- takeAt(i): 移除位于索引位置i的项并返回它。i必须是列表中有效的索引位置(即0 <= I < size())。如果不使用返回值,removeAt()更合适。
这里说明两个方法都是移除QList某一项的方法,不同的地方在于,removeAt()没有返回值,而takeAt()会返回移除的项的值。
简单使用
用一个简单的例子说明一下这两个方法的区别:
QList<int> list;
list << 1 << 2 << 3;
//removeAt
list.removeAt(0);
qDebug() << list; //结果:2,3
//takeAt
int i = list.takeAt(0)
qDebug() << i; //结果:1
qDebug() << list; //结果:2,3
这两个方法都移除了列表的第一项,不同的是,takeAt方法可以返回移除项的值。
特殊使用
当QList中的类型为指针类型时(即每一项存入的都是一个动态创建的内存的指针),移除某一项时的操作:
如果QList为指向T类型项的指针数组,那么QList将项直接存储在指针数组中。
QList只保存你传入的基本指针,而不去或者不能知道这些指针是被怎么创建的,在何处创建的。所以在移除一个指针项时,只是将这个指针从列表中移出,而指针所指向的内存并没有被释放。如果需要释放,那么需要自己手动进行释放。
QList<MyClass *> list;
for(int i=0; i<3; i++)
{
MyClass *myclass = new MyClass(this);
list.append(myclass);
}
//removeAt
removeAt(0); // 移除第0项存放的指针地址, 指针指向的内存没有被释放
//takeAt
MyClass * item = takeAt(0); //移除第0项,并释放该指针指向的内存
delete item;
item = nullptr;
这两个方法都不能实现移除但是不销毁item,我们需要重新创建一个相同的item进行保存。
前言
在使用QListWidget时,有时并不想只用QListWidgetItem作为我们的显示效果,需要将QListWidgetItem设置为我们自定义的一个Widget,并且需要进行添加和删除的操作。QListWidget提供了两个很相似的移除item的方法,removeItemWidget(),一个是takeItem()。在选择这两个方法时产生了疑问,不知道该用哪个,怎么用。于是查阅了官方帮助和网上资料做对比,总结一下这两个方法的区别。
官方解释
- addItem(QListWidgetItem *item): 将项插入到列表小部件的末尾。
- insertItem(int row, QListWidgetItem *item): 将item插入到列表中按行给定的位置。
- setItemWidget(QListWidgetItem *item, QWidget *widget): 设置小部件显示在给定项中。
这个函数应该只用于在指定列表小部件item的位置显示自定义静态内容。如果您想显示自定义动态内容或实现自定义编辑器小部件,请使用QListView和子类QStyledItemDelegate。 - ListWidgetItem *QListWidget::takeItem(int row): 从列表小部件的给定行中移除并返回item;否则返回nullptr。从列表小部件中删除的项目将不会由Qt管理,需要手动删除。
- removeItemWidget(QListWidgetItem *item): 删除在给定项上设置的小部件。removeItemWidget只是删除该item对应的widget,不会删除该item。要从列表中完全删除一个item(row),可以delete该item或使用takeItem()。
简单使用
首先看添加:
QListWidgetItem *item = new QListWidgetItem(); //创建一个item
item->setFlags(Qt::NoItemFlags); //设置item的标志
item->setFlags(Qt::ItemIsEnabled);
item->setSizeHint(QSize(width, height)); //设置item的大小
ui->listWidget->insertItem(0, item); //将item插入到list第0行
MyItem myItem = new MyItem(); //创建一个自定义widget
ui->listWidget->setItemWidget(item, myItem); //将自定义widget设置在item中显示出来
然后看移除:
int i = 0;
QListWidgetItem *item = ui->listWidget->item(i)
ui->listWidget->removeItemWidget(item); //这时这一行仍然存在,显示空白
然后再看删除:
int nRow = 0;
QListWidgetItem *item = ui->listWidget->takeItem(nRow);
delete item;
item = nullptr; //删除一行,记得手动销毁
需要注意的是:
- addItem是在列表末尾插入一行,insertItem是在列表指定位置插入一行。
- setItemWidget是将某一个item设置为自定义的widget显示出来。
- takeItem是删除一行(即一个item),removeItemWidget是将item中的自定义widget移除,并没有删除item。
- setItemWidget和removeItemWidget是一对。
- 删除item时需要手动delete该指针。
- 点赞
- 收藏
- 关注作者
评论(0)