最近項目上有需求,需要對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多行選中并進行刪除代碼及說明,具體后期實現結果如下:
-
數據
+關注
關注
8文章
6713瀏覽量
88300 -
按鍵
+關注
關注
4文章
222瀏覽量
57490 -
代碼
+關注
關注
30文章
4670瀏覽量
67760 -
checkbox
+關注
關注
0文章
3瀏覽量
1079
發布評論請先 登錄
相關推薦
評論