最近项目上有需求,需要对qtableview上的数据进行多选及多行删除。经过多次尝试,总结出了如下方法。
先上最终实现的效果,如下
如上图所示,第一列为checkbox ,第二列为有效数据,可以用多列数据。
注:model_measure为本人绑定tableview所用的model,由于此项未做传参,用的默认的全局变量。
此处参考了网上的资料,具体实现如下:
//设置当前类显示复选框
void MainFrame::SetCurrentRowCheck(int row,bool checked)
{
QStandardItem *item = new QStandardItem();
item->setCheckable(true); //设置可选
if(! checked)
{
item->setCheckState(Qt::Unchecked);
}
else
{
item->setCheckState(Qt::Checked);
}
item->setEditable(false);
model_measure->setItem(row, 0, item); //在第一列用checkbox(0表示第一列,row表示行,可以自由修改)
model_measure->item(row, 0)->setTextAlignment(Qt::AlignHorizontal_Mask); //设置布局
}
如上代码所示,本人将第一列设置为复选框,默认调用此函数,每需要一行新的数据,则调用一次该函数,传入行数及是否选中参数,即可以在第一列,所有行生成checkbox
全选,反选,本人绑定了一个按键实现,代码如下所示:
//全选/反选
void MainFrame::on_pushButton_Select_clicked()
{
for(int i = 0; irowCount(); i++)
{
if(Qt::Unchecked == model_measure->item(i,0)->checkState())
{
SetCurrentRowCheck(i,true); //未选中 则选中
}
else if(Qt::Checked == model_measure->item(i,0)->checkState())
{
SetCurrentRowCheck(i,false); //选中了 则不选中
}
}
}
如上代码所示:
点一次按键,则将未选中的都选中,选中的都置为未选中,反之亦然。
如上实现功能,可以实现每一行的选择,并支持全选/反选的功能。
接下来,来实现一下右键菜单关联
头文件有如下定义:
包括几个变量 和2个槽函数
private:
QMenu *RightClickMenu; //右键点击菜单
QAction *deleteAction; //单行删除事件(如需要其它事件,可新定义)
QAction *deleteMultiAction; //多行删除事件(如需要其它事件,可新定义)
int seletMouseRow; //选择到的表格的行数信息
public slots:
void onGetMousePos(QPoint pos); //菜单 点击 获取当前位置
void onMenuAction(QAction *act); //事件操作
源文件如下:
构造函数:
//必须先对tableview配置如下功能 本人tableview名字叫tableView_Measure
ui->tableView_Measure->setSelectionBehavior(QAbstractItemView::SelectRows);
ui->tableView_Measure->setContextMenuPolicy(Qt::CustomContextMenu);
//菜单等事件
RightClickMenu = new QMenu(); //右键点击菜单
deleteAction = new QAction("删除",this); //单行删除事件
deleteMultiAction = new QAction("多行删除",this); //多行删除
RightClickMenu->addAction(deleteAction); //将action添加到菜单内
RightClickMenu->addAction(deleteMultiAction);
//信号槽连接
connect(ui->tableView_Measure,&QTableView::customContextMenuRequested,this,&MainFrame::onGetMousePos);
connect(RightClickMenu,&QMenu::triggered,this,&MainFrame::onMenuAction);
槽函数1
//获取位置信息
void MainFrame::onGetMousePos(QPoint pos)
{
QModelIndex index = ui->tableView_Measure->indexAt(pos); //找到tableview当前位置信息
seletMouseRow = index.row(); //获取到了当前右键所选的行数
if(index.isValid()) //如果行数有效,则显示菜单
{
RightClickMenu->exec(QCursor::pos());
}
//qDebug() << "curr_row" << seletMouseRow;
}
槽函数2
//菜单操作
void MainFrame::onMenuAction(QAction *act)
{
//删除本行数据
if(act->text() == "删除") //看选中了删除这个菜单
{
//弹出提示框,看是否删除数据
QMessageBox message(QMessageBox::NoIcon, "提示",
"是否删除本行数据?",
QMessageBox::Yes | QMessageBox::No, NULL);
//如确认删除
if(message.exec() == QMessageBox::Yes)
{
model_measure->removeRow(seletMouseRow); //删除掉了表格信息
}
}
//删除多行数据
else if(act->text() == "多行删除")
{
//弹出提示框,看是否删除数据
QMessageBox message(QMessageBox::NoIcon, "提示",
"是否删除所有选中行的数据?",
QMessageBox::Yes | QMessageBox::No, NULL);
//如确认删除多行 则删除多行数据
if(message.exec() == QMessageBox::Yes)
{
QVector<int> row_list;
row_list.clear();
//找到标的序号 必须从最后一行 往前删除 不然会打乱顺序
for(int i = model_measure->rowCount() - 1; i >= 0 ; i--)
{
if(Qt::Checked == model_measure->item(i,0)->checkState()) //i行0列 复选框
{
row_list.push_back(i);
}
}
//根据填充到的数据 删除选中列
for(int j = 0; jremoveRow(row_list.at(j));
}
}
}
}
槽函数2 承担了删除单行和多行的功能
单行删除相对来说比较容易,只要找到槽函数1所对应的行数信息,由于该变量是全局变量,直接删除就行了
多行删除就比较麻烦了,要从最后一行往前删,不然会出现删错行的问题。
四、总结
如上所示,即为tableview多行选中并进行删除代码及说明,具体后期实现结果如下:
全部0条评论
快来发表一下你的评论吧 !