【QT常用技术讲解】QTableView添加QCheckBox、QPushButton
前言
QT展示列表信息的时候通常用到列表(比如用户信息、机构信息、设备信息等菜单),当需要对某列进行修改、删除操作时,就需要加入按钮(QPushButton),当需要对多列进行右键菜单操作时,就需要加入QCheckBox和右键菜单功能,本篇即围绕QTableView、QCheckBox、QPushButton,以及右键菜单进行讲解。
功能显示效果图




功能讲解
1、创建QTableView
(1)创建QTableView列表头
//两种方式创建列表头//1、在UI中之间添加//2、组装QStringList,调用setHorizontalHeaderLabels方法加载进去,列表头不算在数据模型Model里面QStringList tablelHeader;for(int i=0;i<m_all_fieldsHeadname.size();i++) {tablelHeader << m_all_fieldsHeadname[i];}qDebug() << __LINE__ << __FUNCTION__<<tablelHeader;//tablelHeader<< "选择" <<"序号"<<"编码"<<"名称"<<"品牌"<<"类型"<<"IP地址"<<"更新时间"<<"操作";

注意,两种方式在数据展示上没有差别,但存在一个坑:
当使用代码行添加列表头(tablelHeader)时,当设置勾选项(QCheckBox)的信号和槽函数来获取勾选项(QCheckBox)的位置时,会偏差1行,坑的位置是以下代码row在获取最后一行时,返回的是-1,返回值-1其实是无效的意思。
以下是片段代码//关联信号和槽QCheckBox *checkBox = new QCheckBox();connect(checkBox,SIGNAL(stateChanged(int)),this,SLOT(onCheckBoxStateChanged(int)));//实现槽函数
void MainWindow::onCheckBoxStateChanged(int state){QCheckBox *checkBox =qobject_cast<QCheckBox *>(QObject::sender());if(checkBox){int row = ui->tableWidget->indexAt(checkBox->mapTo(ui->tableWidget, QPoint(0, 0))).row();
}
我提交的源代码也是使用代码行添加列表头(tablelHeader),但用了另外一个方法来规避此问题,规避方法是row取的是继承tableWidget获取到的row,而不是通过checkBox->mapTo(ui->tableWidget, QPoint(0, 0))反向获取到的行位置(本人未深入研究mapTo,有用此方法解决此问题的兄弟,可以把代码放在评论区),所以不会出现偏差。
代码如下:
void tab_basemsg::renderTable(const QStringList& rowData){int row = ui->tableWidget->rowCount();//当前tableWidget显示的行数//int rowCount = ui->tableWidget->model()->rowCount();//tableWidget表格中实际的数据行数ui->tableWidget->insertRow(row);//在 QTableWidget 中插入新行for (int column = 0; column < rowData.size(); ++column) {QTableWidgetItem* item = new QTableWidgetItem(rowData.at(column));item->setTextAlignment(Qt::AlignCenter);ui->tableWidget->setItem(row, column, item);if(column == HEAD_BASEMSG_CKBOX){//========创建复选框QCheckBox===============QCheckBox* checkBox = new QCheckBox();QWidget* widget = new QWidget();QHBoxLayout* layout = new QHBoxLayout(widget);layout->addWidget(checkBox);layout->setAlignment(Qt::AlignCenter);layout->setContentsMargins(0, 0, 0, 0);widget->setLayout(layout);if(m_controlstatus==false) checkBox->setEnabled(false); // 设置复选框为不可选中状态else checkBox->setEnabled(true); // 设置复选框为可选中状态connect(checkBox,&QCheckBox::stateChanged,this,[=](int state){//获取当前行的IPQString ip = ui->tableWidget->item(row, HEAD_BASEMSG_IP)->text();//可以继承到row//qDebug()<< __LINE__ << "state:"<<state;qDebug()<< __LINE__ << "row:"<<row << "ip:"<<ip;m_iplist.append(ip);if (state == Qt::Checked) {for(int i=0;i<HEAD_BASEMSG_NUM;i++){QTableWidgetItem *item = ui->tableWidget->item(row, i);//if(i==0) {item->setText("");}item->setBackground(QBrush(QColor("#308cc6")));item->setForeground(Qt::white);}// 改变操作项图标文件(颜色变化)QWidget *container = ui->tableWidget->cellWidget(row, HEAD_BASEMSG_OPT);if (container) {QLayout *layout = container->layout();if (layout) {if (layout) {QPushButton *editbtn = qobject_cast<QPushButton *>(layout->itemAt(0)->widget());QPushButton *deletebtn = qobject_cast<QPushButton *>(layout->itemAt(1)->widget());editbtn->setIcon(QIcon(":/index/img/edit_ch.png"));deletebtn->setIcon(QIcon(":/index/img/delete_ch.png"));}}}}else {for(int i=0;i<HEAD_BASEMSG_NUM;i++){QTableWidgetItem *item = ui->tableWidget->item(row, i);// 设置未选中行的背景颜色为默认颜色item->setBackground(QBrush(Qt::white));item->setForeground(Qt::black);}// 改变操作项图标文件(颜色变化)QWidget *container = ui->tableWidget->cellWidget(row, HEAD_BASEMSG_OPT);if (container) {QLayout *layout = container->layout();if (layout) {if (layout) {QPushButton *editbtn = qobject_cast<QPushButton *>(layout->itemAt(0)->widget());QPushButton *deletebtn = qobject_cast<QPushButton *>(layout->itemAt(1)->widget());editbtn->setIcon(QIcon(":/index/img/edit.png"));deletebtn->setIcon(QIcon(":/index/img/delete.png"));}}}}});ui->tableWidget->setCellWidget(row, column, widget);}if (column == HEAD_BASEMSG_OPT) {//编辑按钮QPushButton* edit = new QPushButton();edit->setIcon(QIcon(":/index/img/edit.png"));edit->setIconSize(QSize(24, 24));edit->setStyleSheet("QPushButton { border: none; }");edit->setCursor(Qt::PointingHandCursor);//删除按钮QPushButton* deleteButton = new QPushButton();deleteButton->setIcon(QIcon(":/index/img/delete.png"));deleteButton->setIconSize(QSize(24, 24));deleteButton->setStyleSheet("background-color:rgba(0,0,0,0);border:none;");deleteButton->setCursor(Qt::PointingHandCursor);//按钮信号监听connect(edit,SIGNAL(clicked()),this,SLOT(editBasemsg()));connect(deleteButton,SIGNAL(clicked()),this,SLOT(delBasemsg()));QWidget* widget = new QWidget();QHBoxLayout* layout = new QHBoxLayout(widget);layout->addWidget(edit);layout->addWidget(deleteButton);layout->setAlignment(Qt::AlignCenter);layout->setContentsMargins(0, 0, 0, 0);widget->setLayout(layout);ui->tableWidget->setCellWidget(row, column, widget);}}
}
(2)QTableView中创建QCheckBox
QCheckBox需要通过widget加载到QTableView中,代码如下:
//创建勾选项QCheckBox* checkBox = new QCheckBox();//创建窗口视图QWidget* widget = new QWidget();//创建布局QHBoxLayout* layout = new QHBoxLayout(widget);//把勾选项加载到布局中layout->addWidget(checkBox);layout->setAlignment(Qt::AlignCenter);layout->setContentsMargins(0, 0, 0, 0);//把布局设置到窗口视图中widget->setLayout(layout);//把窗口视图中展示到tableWidget的指定位置ui->tableWidget->setCellWidget(row, column, widget);
QCheckBox勾选项关联的信号和槽的代码参见【(1)创建QTableView列表头】分享的renderTable()函数源代码。
(3)QTableView中创建QPushButton
QPushButton与QCheckBox一样,也是需要widget加载到QTableView,不过可以设置QPushButton的尺寸、背景颜色等友好展示的布局,源码如下所示:
//编辑按钮QPushButton* edit = new QPushButton();edit->setIcon(QIcon(":/index/img/edit.png"));edit->setIconSize(QSize(24, 24));edit->setStyleSheet("QPushButton { border: none; }");edit->setCursor(Qt::PointingHandCursor);//删除按钮QPushButton* deleteButton = new QPushButton();deleteButton->setIcon(QIcon(":/index/img/delete.png"));deleteButton->setIconSize(QSize(24, 24));deleteButton->setStyleSheet("background-color:rgba(0,0,0,0);border:none;");deleteButton->setCursor(Qt::PointingHandCursor);//按钮信号监听connect(edit,SIGNAL(clicked()),this,SLOT(editBasemsg()));connect(deleteButton,SIGNAL(clicked()),this,SLOT(delBasemsg()));QWidget* widget = new QWidget();QHBoxLayout* layout = new QHBoxLayout(widget);layout->addWidget(edit);layout->addWidget(deleteButton);layout->setAlignment(Qt::AlignCenter);layout->setContentsMargins(0, 0, 0, 0);widget->setLayout(layout);ui->tableWidget->setCellWidget(row, column, widget);
(4)QTableView创建右键菜单
①在头文件中添加右键菜单绑定的槽函数,源码如下:
//tab_basemsg.h
private slots://处理右键菜单请求void tableWidget_MenuRequested(const QPoint &pos);
②设置右键功能及关联信号和槽,并实现槽函数(在槽函数中增加具体的右键菜单名称),源码如下:
//tab_basemsg.cpp
//设置右键菜单功能
ui->tableWidget->setContextMenuPolicy(Qt::CustomContextMenu);
//绑定右键功能槽函数
connect(ui->tableWidget, &QTableWidget::customContextMenuRequested, this, &tab_basemsg::tableWidget_MenuRequested);//槽函数实现
void tab_basemsg::tableWidget_MenuRequested(const QPoint &pos) {QModelIndex index = ui->tableWidget->indexAt(pos);//获取当前行if (!index.isValid()) return;QMenu menu(this);QAction *DiplaymsgAction = menu.addAction(tr("查看详情"));connect(DiplaymsgAction,&QAction::triggered,[=](){//获取选择的单元格QList<QTableWidgetItem *> selected_cells = ui->tableWidget->selectedItems();if(!selected_cells.isEmpty()){QTableWidgetItem *codeCell = ui->tableWidget->item(selected_cells.first()->row(),HEAD_BASEMSG_CODE);if(codeCell!=nullptr){QString code = codeCell->text();stBasemsg basemsg=m_basemsgmap[code];basemsgDialg->setModal(false);basemsgDialg->setWindowTitle("保存");//basemsgDialg->setFixedSize(500,400);basemsgDialg->open();basemsgDialg->init(1,basemsg);basemsgDialg->exec();}}});QAction *NetpingAction = menu.addAction(tr("Ping此计算机"));connect(NetpingAction,&QAction::triggered,[=](){//获取选择的单元格QList<QTableWidgetItem *> selected_cells = ui->tableWidget->selectedItems();if(!selected_cells.isEmpty()){QTableWidgetItem *codeCell = ui->tableWidget->item(selected_cells.first()->row(),HEAD_BASEMSG_CODE);if(codeCell!=nullptr){QString code = codeCell->text();stBasemsg basemsg=m_basemsgmap[code];QString ip=basemsg.Ip;qDebug() << __LINE__ << ip;pingdlg->setIp(ip);pingdlg->setModal(false);pingdlg->setWindowTitle("PING测试");pingdlg->setFixedSize(500,400);pingdlg->open();pingdlg->init();pingdlg->exec();}}});menu.exec(QCursor::pos());//menu.exec(ui->tableWidget->mapToGlobal(pos));
}
篇尾
因为多个勾选项很多情况下涉及多项数据的处理,有些处理是要异步才不会导致主界面卡顿,下一篇用多线程+ping+全局变量+结果展示技术点(【QT常用技术讲解】多线程处理+全局变量处理异步事件并获取多个线程返回的结果),来详细讲解【多线程解决QTableView多勾选项右键菜单功能卡顿问题】。
相关文章:
【QT常用技术讲解】QTableView添加QCheckBox、QPushButton
前言 QT展示列表信息的时候通常用到列表(比如用户信息、机构信息、设备信息等菜单),当需要对某列进行修改、删除操作时,就需要加入按钮(QPushButton),当需要对多列进行右键菜单操作时࿰…...
linux监控命令
在 Linux 中,有许多命令可以用于监控系统的性能和状态。以下是一些常用的监控命令及其用途: 1. top 和 htop top top 命令显示当前系统中运行的进程列表及其资源使用情况。 top htop htop 是 top 命令的增强版,提…...
SpringBoot入门笔记
本文是看黑马老师讲课视频学习笔记整理 目录 入门案例 基于IDEA联网 基于Springboot官网创建 基于阿里云创建项目 手工创建 隐藏文件 入门案例解析: parent编辑 starter 引导类 内嵌tomcat 入门案例 基于IDEA联网 RestController RequestMapping("/books&…...
python 华为od 单词接龙
sd[word,dd,da,dc,dword,d] # 计算出下一个接龙单词 def jl(sd,st):# sd.remove(st)sd list(set(sd))sends list(st)[-1]lg []sd.sort()for i in sd:if i.startswith(sends):lg.append((i, len(i)))if lg[]:return 0,0lg.sort(keylambda x: x[1],reverseTrue)maxlen lg[0][…...
Vue+Echart实现地图省市区三级下钻
采用在线地图数据,整体简约,扩展也方便 参考 <template><div><div ref"mapContainer" style"width: 100%; height: 600px;"></div><button click"goBack">返回上一级</button></…...
Apache Tomcat 信息泄露漏洞排查处理CVE-2024-21733)
一、漏洞描述 Apache Tomcat作为一个流行的开源Web服务器和Java Servlet容器并用于很多中小型项目的开发中。其中,Coyote作为Tomcat的连接器组件,是Tomcat服务器提供的供客户端访问的外部接口,客户端通过Coyote与服务器建立链接、发送请求并且接收响应。 近日发现Apache To…...
51单片机-LED实验
实现了按下独立按键,LED灯亮,松开独立按键,LED灯灭的功能 #include <8051.h>void delayms(unsigned char t){unsigned char i,j;i900;jt;do{jt;while (j--){/* code */}}while(i--); }void main(){// P2_01;while (1){if(P3_00){delay…...
无人机开启农林植保新篇章
嘿,小伙伴们,你们知道吗?无人机已经悄悄在农业领域大展拳脚,成为现代农业的“黑科技”新宠儿啦! 想象一下,广袤的田野上空,无人机如同勤劳的蜜蜂,精准高效地完成着各项任务ÿ…...
第N4周:NLP中的文本嵌入
本文为365天深度学习训练营 中的学习记录博客原作者:K同学啊 任务要求:加载第N1周的.txt文件,使用Embeddingbag与Embedding完成词嵌入 第N1周的.txt文件的名称为“任务文件.txt”,内容为: 比较直观的编码方式是采用上…...
C++高精度减法
高精度减法其实跟加法差不多,首先就是需要逆序存入整数数组,其次就是做运算,最后就是删除前导0逆序输出。 不过在做高精度减法需要考虑一下两个数的关系是有三种的,a>b,a<b ab;思考全面咱们的程序才能拿满分。 以下是完整…...
protobuf cmakelist,msvc utf-8设置
源字符集和执行字符集 源字符集指的是cpp文件中字符串的编码方式 执行字符集指的是exe文件中字符串的编码方式 msvc编译器设置的命令行参数 /source-charset:utf-8 /execution-charset:utf-8 cmake中设置 add_compile_options(“ < < <<CXX_COMPILER_ID:MSVC>…...
Haproxy讲解
Haproxy: haproxy是一个开源的高性能反向代理和负载均衡器,主要用于TCP和HTTP流量管理。 功能和特点:haproxy能够处理大量的并发连接,支持TCP和HTTP协议,具有高可用性和负载均衡功能。它特别适用于需要处理大量流量的网站&am…...
K8S系列——一、Ubuntu上安装Helm
在使用K8S搭建集群服务时,有时候需要用到Helm(一个用于Kubernetes应用管理的工具),下面是在Ubuntu上安装Helm的过程。 1.更新系统软件包列表 sudo apt-get update2.安装必要的依赖项 sudo apt-get install apt-transport-https…...
排序: 插入\希尔\选择\归并\冒泡\快速\堆排序实现
1.排序的概念及应用 1.1概念 排序:所谓排序,就是一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。 1.2运用 购物筛选排序: 1.3常见排序算法 2.实现常见的排序算法 int a[ {5,3,9,6,2,4,7,1,8}; 2…...
OpenCV图像处理——按最小外接矩形剪切图像处理ROI后映射回原图像
引言 在图像处理过程中,提取感兴趣区域(ROI)并在其上进行处理后,往往需要将处理后的结果映射回原图像。这一步通常涉及以下几个步骤: 找到最小外接矩形:使用 cv::boundingRect 或 cv::minAreaRect 提取感兴…...
Linux中以单容器部署Nginx+ASP.NET Core
强烈推荐在生产环境中使用反向代理服务器转发请求到Kestrel Http服务器,本文将会实践将Nginx --->ASP.NET Core 部署架构容器化的过程。 Nginx->ASP.NET Coe部署架构容器化 在Docker中部署Nginx--->ASP.NETCore 有两种选择, 第一种是在单容器…...
【秋招笔试】8.11大疆秋招(第三套)-三语言题解
🍭 大家好这里是 春秋招笔试突围,一起备战大厂笔试 💻 ACM金牌团队🏅️ | 多次AK大厂笔试 | 编程一对一辅导 ✨ 本系列打算持续跟新 春秋招笔试题 👏 感谢大家的订阅➕ 和 喜欢💗 和 手里的小花花🌸 ✨ 笔试合集传送们 -> 🧷春秋招笔试合集 🍒 本专栏已收…...
标题:打造编程学习的知识宝库:高效笔记记录与整理
标题:打造编程学习的知识宝库:高效笔记记录与整理 在编程学习的征途中,有效的笔记记录和整理技巧对于掌握和回顾知识点至关重要。本文将从笔记工具选择、笔记结构设计、以及实践与复习策略三个方面,探讨如何高效地记录并整理编程…...
【Rust光年纪】Rust 官方提供的关键工具概览:代码检查、格式化和依赖管理
提升 Rust 项目质量和安全性:掌握官方工具的核心功能和使用方法 前言 Rust 作为一种系统编程语言,拥有强大的性能和内存安全特性。然而,随着项目规模增长,代码检查、格式化和依赖管理等工作变得更加重要。因此,Rust …...
【Python学习-UI界面】PyQt5 小部件8-QSlider 数值滑动
样式如下: QSlider 类对象为用户提供一个沟槽,可以在其上移动一个手柄。 它是一个经典的小部件,用于控制有界值。 手柄在沟槽上的位置相当于控件的下限和上限之间的整数。 常用方法如下: 序号方法描述1setMinimum设置滑块的最小值2setMax…...
最新陪玩陪聊系统网站源码 娱乐交友系统公众号版
内容目录一、详细介绍二、效果展示1.部分代码2.效果图展示一、详细介绍 最新陪玩陪聊系统网站源码 娱乐交友系统 附安装教程 二、效果展示 1.部分代码 代码如下(示例): <section id"cliens" class"cliens section-bg&…...
【Linux C++ 日志系统实战】LogFile 日志文件管理核心:滚动策略、线程安全与方法全解析
前言在 Linux 后端开发中,日志系统不仅要能 “写得快”,更要能 “管得好”—— 比如日志文件过大导致磁盘占满、跨天日志混在一起难以排查、多线程写入乱码、崩溃后日志丢失等问题,都需要一个专业的 “文件管理器” 来解决。本文的核心主角 L…...
企业级 Agent 治理平台:公司用数字帮手的必备管家
个人用智能体这个数字帮手,自己教、自己用,出点小问题也就影响自己;但公司里用,几十上百个智能体一起跑,要是没人管,麻烦事就多了:有的智能体可能随便翻公司的敏感数据,有的学会的好…...
C# DOTS内存暴涨真相(ECS组件碎片化大揭秘):基于IL2CPP内存快照的12类GC压力源定位指南
第一章:C# DOTS内存暴涨真相(ECS组件碎片化大揭秘)在Unity DOTS(Data-Oriented Technology Stack)实践中,许多开发者遭遇了看似“无故”的内存持续增长现象——托管堆(Managed Heap)…...
从硬件小白到项目上线:我的第一个STM32物联网项目(小熊派智慧路灯踩坑实录)
从硬件小白到项目上线:我的第一个STM32物联网项目(小熊派智慧路灯踩坑实录) 第一次拿到小熊派开发板时,那种既兴奋又忐忑的心情至今记忆犹新。作为一个刚转行物联网开发的菜鸟,我对着这块印着卡通熊标志的绿色电路板发…...
Gemma-3-270m在QT桌面应用中的集成开发指南
Gemma-3-270m在QT桌面应用中的集成开发指南 1. 引言 想在桌面应用中添加智能对话功能吗?Gemma-3-270m这个轻量级AI模型可能正是你需要的解决方案。作为Google最新推出的紧凑型语言模型,它只有2.7亿参数,却能在普通电脑上流畅运行࿰…...
基于YOLOv11深度学习的蘑菇毒性检测系统(YOLOv11+YOLO数据集+UI界面+登录注册界面+Python项目源码+模型)
一、项目介绍 本项目基于 YOLOv11(You Only Look Once v11)轻量化深度学习目标检测算法,构建了一套端到端的蘑菇毒性检测系统,旨在解决传统蘑菇毒性鉴别依赖专业知识、效率低且易出错的问题。系统面向普通用户、食品安全监管人员…...
vscode-mermaid-preview插件:从零开始掌握Mermaid图表绘制的完整指南
vscode-mermaid-preview插件:从零开始掌握Mermaid图表绘制的完整指南 【免费下载链接】vscode-mermaid-preview Previews Mermaid diagrams 项目地址: https://gitcode.com/gh_mirrors/vs/vscode-mermaid-preview 如果你正在Visual Studio Code中编写技术文档…...
数据本体论 vs 数仓实体建模?
一、定义与起源 维度 数据本体论 (Data Ontology) 数仓实体建模 定义 哲学“存在论”在计算机领域的应用,强调语义统一 数据库ER建模方法,强调数据结构化与存储优化 核心思想 以“概念/类”为中心,描述事物“是什么”及“为何关联” 以“…...
Python实战:单细胞转录因子分析全流程解析
1. 单细胞转录因子分析入门指南 单细胞转录因子分析是近年来单细胞测序领域的热门方向,它能帮助我们从海量单细胞数据中挖掘调控细胞命运的关键转录因子。想象一下,这就像是在茫茫人海中找到那些真正影响群体行为的关键人物。传统方法需要复杂的生物信息…...
