今天主要介绍QT中tabwidget的用法,即怎样利用表格存储数据并对表里的数据进行其他类似excel 的操作,具体包括:

1.选中方式,单行选中或者多行选中;

2.复制行,可以将单行或者多行选中的内容复制到剪贴板,之后就可以复制到excel或者其他任何地方;

3.多选行,选中单行或者选中多行甚至全选;

4.删除,删除所选中行或者清空整个tabwidget等功能;

主要想实现的效果如下:

https://www.zhihu.com/video/1160235716704964608

我们要实现的功能对应到ui上是鼠标右键的下拉菜单,这里就必须实现contextMenuEvent事件重写:

具体实现为如下代码:

/// 在tabwidget上增加鼠标右键下拉菜单,并增加五种对应子功能:单行复制、带表头复制、单行删除、全删、全选;
void contextMenuEvent(QContextMenuEvent* e)
{// 首先判断鼠标目前位置是否在tablewidget上if(ui->tableWidget_results_info->underMouse()){QMenu *menu = new QMenu();menu->addSeparator();menu->addSeparator();QAction*    Act_Copy;QAction*    Act_Copy_with_Header;QAction*    Act_Delete;QAction*    Act_Delete_All;QAction*    Act_Selete_All;Act_Copy = new QAction(tr("复制"), this);//想要添加icon图标的话可以使用seticon实现//    Act_Copy->setIcon(QIcon("Resources/logo.png"));Act_Copy_with_Header = new QAction(tr("带表头复制"), this);//    Act_Copy_with_Header->setIcon(QIcon("Resources/logo.png"));Act_Delete = new QAction(tr("删除"), this);Act_Delete_All = new QAction(tr("删除全部"), this);Act_Selete_All = new QAction(tr("全选"), this);menu->addAction(Act_Copy);menu->addSeparator();menu->addSeparator();menu->addAction(Act_Copy_with_Header);menu->addSeparator();menu->addSeparator();menu->addAction(Act_Delete);menu->addSeparator();menu->addSeparator();menu->addAction(Act_Delete_All);menu->addSeparator();menu->addSeparator();menu->addAction(Act_Selete_All);menu->addSeparator();menu->addSeparator();// 连接各个功能对应的实现槽函数connect(Act_Copy, SIGNAL(triggered()), this, SLOT(Copy_Line()));connect(Act_Copy_with_Header,  SIGNAL(triggered()), this, SLOT(Copy_Lines()));connect(Act_Delete, SIGNAL(triggered()), this, SLOT(Delete_Line()));connect(Act_Delete_All, SIGNAL(triggered()), this, SLOT(Delete_Lines()));connect(Act_Selete_All, SIGNAL(triggered()), this, SLOT(Selete_Lines()));menu->exec(e->globalPos());delete menu;}
}

然后具体说明以下函数具体内容:首先我们要明确先要实现选择区域范围的读取然后再对应到子功能上,打比方就是:如果是全选内容后,复制操作则是复制全选的内容;如果是选择的是某一行,那么复制操作则是复制选中的某一行的内容即可;同理,删除也是一样的思路;所以这里首先说明获取tabwidget中选中区域的范围;即起始行和终止行的行数,当选中的是某一行时,这两个值是同一值而已;

QT中的selectedRanges()函数就是帮助我们获取当前tabwidget中选中区域的范围,返回值是Qlist类型,其中包括4个值,即top(起始行), bottom(终止行),left(起始列)和right(中止列);

QList<int> selete_line_range(){QList<QTableWidgetSelectionRange> range = ui->tableWidget_results_info->selectedRanges();// 因为我们设置了tabwidget的选中方式为行选中,所以关于列的两个参数对我们没有帮助int top, bottom;// 当选中的区域是单行时,list仅有1个元素,所以直接读取id为0的top和bottomif(1==range.length()){top    = range[0].topRow();bottom = range[0].bottomRow();}// 当选中的区域为全选时,list会有多个元素,所以起始行则为id为0的top,终止行为id是list最后一个元素的bottomelse {top    = range[0].topRow();bottom = range[range.length()-1].bottomRow();}// 将获取到的top和bottom两个值放进新的QList并返回以供调用QList<int> range_final;range_final.append(top);range_final.append(bottom);return range_final;
}

全选功能:

void Selete_Lines(){printf("Selete_Lines");// 首先更改行选中方式为多行选中ui->tableWidget_results_info->setSelectionMode(QAbstractItemView::MultiSelection);// 清空目前所选高亮行ui->tableWidget_results_info->clearSelection();// 获取当前所有行数目int rows = ui->tableWidget_results_info->rowCount();for(int subrow=0; subrow<rows; subrow++){// 当每行第一个cell值不为空时直接选中此行,反之,不做任何操作if(ui->tableWidget_results_info->item(subrow, 0)!=NULL){ui->tableWidget_results_info->selectRow(subrow);}}// 最后更改行选中方式为extend,这种选中方式即一般为单行选中,当使用ctrl键辅助则可多行选中ui->tableWidget_results_info->setSelectionMode(QAbstractItemView::ExtendedSelection);
}

复制功能:

void Copy_Line(){printf("Copy_Line");QList<int> range_final = selete_line_range();int row_start=range_final[0];int row_end = range_final[1];int colnum = ui->tableWidget_results_info->columnCount();QString clipText;QString text;for(int subrow=row_start; subrow<=row_end; subrow++){for(int subcol=0; subcol<colnum; subcol++){// 当cell不为空时获取文本,否则设置为“”if(ui->tableWidget_results_info->item(subrow, subcol)!=NULL)text = ui->tableWidget_results_info->item(subrow, subcol)->text();else {text= "";}clipText.append(text);clipText.append("t");}clipText.append("n");}clipText.chop(1);//删除末尾一个字符clipText.append("n");// 将获取的文本放到剪贴板QClipboard *clipboard = QApplication::clipboard();clipboard->clear();clipboard->setText(clipText);
}

带表头复制:

void Copy_Lines(){printf("Copy_Lines");int colnum = ui->tableWidget_results_info->columnCount();QString clipText;// 先复制表头for(int col=0; col<colnum; col++){QString text;if(ui->tableWidget_results_info->horizontalHeaderItem(col)!=NULL)//这个很重要text = ui->tableWidget_results_info->horizontalHeaderItem(col)->text();else {text= "";}clipText.append(text);clipText.append("t");}// 表头和行之间不要忘记换行符clipText.append("n");QList<int> range_final = selete_line_range();int row_start=range_final[0];int row_end = range_final[1];QString text;for(int subrow=row_start; subrow<=row_end; subrow++){for(int subcol=0; subcol<colnum; subcol++){if(ui->tableWidget_results_info->item(subrow, subcol)!=NULL)text = ui->tableWidget_results_info->item(subrow, subcol)->text();else {text= "";}clipText.append(text);clipText.append("t");}// 行与行之间也不要忘记换行符clipText.append("n");}clipText.chop(1);//删除末尾一个字符clipText.append("n");clipboard->clear();clipboard->setText(clipText);
}

删除功能:

void Delete_Line(){printf("Delete_Line");int rowcount = ui->tableWidget_results_info->rowCount();QList<int> range_final = selete_line_range();int row_start=range_final[0];int row_end = range_final[1];for(int subrow=row_start; subrow<=row_end; subrow++){// 删除一行内容后为了保证原表行数不变则需要移除动作之后随即插入新行ui->tableWidget_results_info->removeRow(row_start);ui->tableWidget_results_info->insertRow(rowcount-1);}
}

清空功能:

void Delete_Lines(){printf("Delete_Lines");ui->tableWidget_results_info->clearContents();
}

我们的实现效果如下:

https://www.zhihu.com/video/1160248336484986880

qt qstandarditemmodel rowcount获取行数不正确_MIL+QT实践教程十相关推荐

  1. 内存映射获取行数_使用内存映射文件获取巨大的矩阵

    内存映射获取行数 总览 矩阵可能真的很大,有时甚至比您可以容纳在一个数组中的要大. 您可以通过具有多个数组来扩展最大大小,但这会使堆大小确实很大且效率低下. 一种替代方法是在内存映射文件上使用包装器. ...

  2. python怎么选取第几行第几列_python DataFrame获取行数、列数、索引及第几行第几列的值方法...

    python DataFrame获取行数.列数.索引及第几行第几列的值方法 更新时间:2018年04月08日 16:22:00 作者:小白九九 下面小编就为大家分享一篇python DataFrame ...

  3. Android textView 获取行数

    Android textView 计算行数 今天要做一个功能,给textView赋值,如果大于三行,初始化显示三行多出的用省略号代替,在下面显示查看更多,小于三行,隐藏查看更多,这个需求本来很简单,就 ...

  4. dataframe 获取行数和列数

    获取行数 df.shape[0] # 或者 len(df) 获取列数 df.shape[1]

  5. Resultset获取行数和列数

    为什么80%的码农都做不了架构师?>>>    在Java中,获得ResultSet的总行数的方法有以下几种.  第一种:利用ResultSet的getRow方法来获得ResultS ...

  6. php预处理获取改变行数,php – 使用MySQLi预处理语句时无法获取行数...

    如果要使用mysqli_stmt :: $num_rows(即,检查预准备语句中的行数),则需要在执行预准备语句之后使用$stmt-> store_result(),然后才能检查其数量行.这意味 ...

  7. python 矩阵获取行数_4个最佳项目创意的代码片段和示例,旨在为Python和机器学习构建出色的简历!...

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 一篇文章带你了解4个最佳项目创意的代码片段和示例 Python是一 ...

  8. Java mysql获取行数_java – MySQL查询获取球体中的行(X,Y,Z坐标)?

    我正在制作一个名为Minecraft with Bukkit API的游戏插件. 我有一个名为Reinforcements的数据库表,其中包含以下字段:x integer,y integer,z in ...

  9. QT应用程序-获取Application-获取主窗口指针-QT内嵌浏览器-QT菜单动作

    在编写QT程序时,有时需要获取主窗口程序指针和主窗口指针,方便控制界面,编写相应的逻辑,而QT则提供了类似的功能. 1.获取应用程序 qApp 宏就可以获取 QApplication 实例,只要使用了 ...

最新文章

  1. mysql合并查询结果及为表和字段取别名
  2. C#实现的【阿拉伯数字转换成中文大写金额】
  3. 数字证书文件格式(cer和pfx)的区别
  4. 学习总结:CSS(一)定义方式、选择器、选择器权重
  5. Hash Table Benchmarks
  6. 3.Your First Machine Learning Model
  7. 计算机留言板毕业论文摘要,留言板系统设计(毕业论文)
  8. 苹果屏幕镜像_苹果屏幕镜像一直在转,秒懂投屏帮你解决
  9. 生命科学主要供应商排行榜
  10. 好玩的海外游戏集结,有没有你玩过的?
  11. 模拟NAND FLASH 读写BCH ECC校验
  12. linux 命令大全_11个炫酷的Linux终端命令大全
  13. 词向量化 Vector Representation of Words 方法汇总
  14. Flutter学习第十五天:2021年最新版超详细Flutter实现Mob+SMSSDK手机验证码登录实现,Android和Flutter混合开发?
  15. linux教程for语句,Bash 中的 For 循环详解
  16. python workflow_Python新手也会写的Alfred Workflow
  17. 解读:电子合同存证五问五答
  18. 数字孪生是什么?如何落地?
  19. 一个网页版的随机点名系统
  20. 票据系统对子票区间的一个应用

热门文章

  1. C#常见算法题目(面试准备)
  2. 问题四十七:怎么用ray tracing画superellipsoid (2)
  3. 问题二十七:ray traing中的positionable camera
  4. Java中 LocalDate、LocalTime、LocalDateTime三个时间工具类的使用介绍
  5. 正向代理 smtp imap_Nginx代理模式及区别
  6. python创建矩阵_从文本文件创建矩阵-python
  7. python语句命令的概念_Python学习笔记1-基础概念
  8. 安装卡主_吸顶灯怎么安装 吸顶灯安装方法【技巧】
  9. Activity管理类,随时随地退出应用程序
  10. 生存分析——泊松回归(LightGBM)实现生存分析(四)