最近需要使用QListWidget完成一个样本输入显示及交互的功能
需要实现的功能基本是这样的:
点击添加样本 将txt文件名输入到左侧的列表中
单击、shift/ctrl多选item后点击移除样本 将样本从列表中移除
点击清空列表,则将列表中的list清空
注:这里只涉及文件名的显示与删除,不涉及文件的读写
基本上涉及到了QListWidget的很多基础用法 ,总结如下
(由于添加样本且不允许重复打开文件,这个功能相对删除文件稍微复杂一些,因此先解释如何实现删除文件)
一、移除选中的文件
先上代码:
/**
* @brief KNNDlg::on_deleteSpfiles_clicked删除选中的样本文件
*/
void KNNDlg::on_deleteSpfiles_clicked()
{
QList <QListWidgetItem*> items ;//注意 items是个Qlist 其中的元素是QListWidgetItem
items=ui->SPList->selectedItems();
if(items.size()==0)
return;
else
{
for(int i =0; i<items.size(); i++)//遍历所算的ITEM
{
QListWidgetItem*sel = items[i];
int r = ui->SPList->row(sel);
delete ui->SPList->takeItem(r);
}
//下面代码可实现删除单选的item
// QListWidgetItem *item = ui->SPList->takeItem(ui->SPList->currentRow());
// delete item;
}
}
原理很简单 有几点需要注意
1、删除Item 需要使用函数takeItem 而不是removeItemWidget
2、由于我们要实现的是删除选中的文件 ,需要使用到selectedItems这个函数
这个函数返回的是QList<QListWidgetItem>格式 因此,我们再保存所选中的文件时需要声明一个这样的对象
3、注意takeItem()这个函数,他的参数是int row ,因此我们需要先读取每个item的row然后 执行takeItem 将这个Item和listWidget 脱离关系
之后用delete来删除
4、是否能多选 可以通过代码进行设置,但是我是通过ui文件直接拖入的控件,所以直接在ListWidget的属性里将selectionMode改为多选模式
二、清空list
这个和删除选中文件是原理是一样的 widget调用一个selectAll()即可
三、向ListWidget中添加文件
代码如下
/**
* @brief KNNDlg::on_InputSP_clicked 输入样本文件
*/
void KNNDlg::on_InputSP_clicked()
{
spFileNames=QFileDialog::getOpenFileNames(this,"样本文件选择","C:\\Users\\gaohan\\Desktop\\GF-5_2\\train data","TXT FILE(*.txt);;SHP FILE(*.shp);;All files(*.*)");
if (spFileNames.length()==0)
{
QMessageBox::information(NULL,"样本文件选择 ","未添加样本文件.");
}
nspfcount=spFileNames.count();
spfcount=ui->SPList->count();
if(spfcount>0)//为防止重复加入,列表不为空时,用新加入的文件遍历列表中的文件 如果有相同的 则提示并返回
{
for(int i=0;i<spfcount; i++)
{
for(int j=0;j<nspfcount;j++)
{
if(spFileNames.value(j)==ui->SPList->item(i)->text())// 注意 这里用==
{
QMessageBox::information(NULL,"样本文件选择",tr("%1 此样本文件已添加").arg(spFileNames.value(j)));
return;
}
}
}
ui->SPList->insertItems(0,spFileNames);
}
else
{
ui->SPList->insertItems(0,spFileNames);//将样本文件名在listWidget中显示
}
}
向ListWIdget中插入item本来很简单,使用insterItem即可解决,
有一个问题是当我重复加入一个文件时,提示我此文件已加入过
使用QFileDialog::getOpenFileNames返回的值保存在QStringList中 (要新加入的文件名)
而ListWidget中保存的是Item(已有的文件名); 两者无法直接对比,而对于小白的我,对两个类的函数又不熟悉
因此走了不少弯路(譬如说还尝试过将打开的文件名累积保存在一个QStringList 中,利用其removeDuplicates()来去重,但实际操作中会产生很多bug)
但最后还是试出来来了 也就是QString的value和item的text() 将新加入的文件名和已存在的文件名一个一个进行对比,如果相同 则提示已加入
效果如下: