Qt关于列表删除操作的详细解析

举报
黑兔子 发表于 2022/09/16 09:36:49 2022/09/16
【摘要】 使用QList时,进行删除某一项的操作,QList提供了两个移除的方法,一个是removeAt(),一个是takeAt()。总结一下这两个方法的区别。在使用QListWidget时,有时并不想只用QListWidgetItem作为我们的显示效果,需要将QListWidgetItem设置为我们自定义的一个Widget,并且需要进行添加和删除的操作。

前言

在使用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该指针。
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。