如何对qtableview上的数据进行多选及多行删除

描述

最近项目上有需求,需要对qtableview上的数据进行多选及多行删除。经过多次尝试,总结出了如下方法。

先上最终实现的效果,如下

按键

如上图所示,第一列为checkbox ,第二列为有效数据,可以用多列数据。

注:model_measure为本人绑定tableview所用的model,由于此项未做传参,用的默认的全局变量。

一、tableview添加checkbox

此处参考了网上的资料,具体实现如下:

//设置当前类显示复选框
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

二、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多行选中并进行删除代码及说明,具体后期实现结果如下:

按键

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分