最近做个项目里想在页面里加一个带复选框可多选的表格。然后使用QT的TableView控件来实现表格的绘制。
最后一列启动复选框,参考别人的方法,很简单实现了。
ui->TableView3->setSelectionMode(QAbstractItemView::SelectionMode::MultiSelection);//开启多选
ui->TableView3->setSelectionBehavior(QAbstractItemView::SelectRows);//设置选中整行,整行高亮
ui->TableView3->setStyleSheet("QTableView::item::selected{background-color:#004D40;}");//设置行选中时的颜色:深绿
QStandardItem *item = new QStandardItem(data);
analyModel->setItem(row, column, item);
if (column == 11) {
item->clearData();
item->setCheckable(true);
item->setCheckState(Qt::Unchecked); // 初始状态为未选中
}
想要实现单击后复选框能有动作还需要设置信号的槽函数,参照别人的方法,很容易实现了。
鼠标点击单元格和直接点击复选框会触发如的信号。
点击单元格:
QAbstractItemView::void clicked(const QModelIndex &index);
直接点击复选框会触发两个信号,signal发出的顺序是:
QStandardItemModel::void itemChanged(QStandardItem *item);
QAbstractItemView::void clicked(const QModelIndex &index);
connect(analyModel,&QStandardItemModel::itemChanged,[=](QStandardItem *item)
{
qDebug()<<"itemChanged";
currentItem=item;
}
void MainWindow::on_tableView_clicked(const QModelIndex &index)
{
QStandardItem *it=analyModel->itemFromIndex(index);
if(currentItem==it)//防止鼠标点击一次,itemChanged触发两次
{
currentItem=nullptr;
return;
}
if(it->checkState()==Qt::Checked)it->setCheckState(Qt::Unchecked);
else if(it->checkState()==Qt::Unchecked)it->setCheckState(Qt::Checked);
currentItem=nullptr;
}
这个槽函数还实现了点击单元格内的任何地方都能实现勾选的动作。
这时候我就想要实现勾选复选框对应的行也跟着高亮,网上使用的方法最多就是
ui->TableView3->setCurrentIndex(ui->TableView3->model()->index(row,0));
或者是
ui->TableView3->setCurrentIndex(analyModel->indexFromItem(currentItem));
我们可以把高亮操作的语句加入到槽函数,点击时就直接高亮了起来。
遇到的问题来了,点击勾选复选框高亮可以,但是取消勾选怎么取消某一行高亮?取消只有一个clear是清除所有。。。
经过测试发现执行两遍setCurrentIndex就可以实现取消该行的高亮。这个方法有一定风险,先放这。
对槽函数进行微调,实现勾选复选框就可以高亮对应的行,取消勾选就取消高亮。
代码比较简单,就算把setCurrentIndex的语句加到槽函数里if(currentItem==it)语句下面,就不添加了。
看似完成了,进行一个快速点的测试,毕竟我们人工手速有时候不会点击完一个复选再等一秒去点下一个复选框。
更大的问题又来了,快速点击时有时候会出现高亮“丢了”的现象,例如连续点击4个复选框,序号来就是0、1、2、3,单击完2(第三个复选)后对应的行高亮了,再单击第4个,就变成了0和1高亮,2没有高亮,高亮“丢了”和3没有高亮。
在槽函数最后面加下面的语句抓一下看看:
QModelIndexList list = ui->fenxiTableView3->selectionModel()->selectedIndexes();
qDebug()<<"list sum:"<<list.count()<<"::"<<list;
发现果然有问题,在2(第三个)单击完之后,Model丢了。。。。
最后还是决定放弃勾选复选框对应的行也跟着高亮这个方案。