当前位置: 首页 > news >正文

【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展示列表信息的时候通常用到列表&#xff08;比如用户信息、机构信息、设备信息等菜单&#xff09;&#xff0c;当需要对某列进行修改、删除操作时&#xff0c;就需要加入按钮&#xff08;QPushButton&#xff09;&#xff0c;当需要对多列进行右键菜单操作时&#xff0…...

linux监控命令

在 Linux 中&#xff0c;有许多命令可以用于监控系统的性能和状态。以下是一些常用的监控命令及其用途&#xff1a; 1. top​ 和 htop​ top ​top​ 命令显示当前系统中运行的进程列表及其资源使用情况。 top​​ ‍ htop ​htop​ 是 top​ 命令的增强版&#xff0c;提…...

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实现地图省市区三级下钻

采用在线地图数据&#xff0c;整体简约&#xff0c;扩展也方便 参考 <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实验

实现了按下独立按键&#xff0c;LED灯亮&#xff0c;松开独立按键&#xff0c;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…...

无人机开启农林植保新篇章

嘿&#xff0c;小伙伴们&#xff0c;你们知道吗&#xff1f;无人机已经悄悄在农业领域大展拳脚&#xff0c;成为现代农业的“黑科技”新宠儿啦&#xff01; 想象一下&#xff0c;广袤的田野上空&#xff0c;无人机如同勤劳的蜜蜂&#xff0c;精准高效地完成着各项任务&#xff…...

第N4周:NLP中的文本嵌入

本文为365天深度学习训练营 中的学习记录博客原作者&#xff1a;K同学啊 任务要求&#xff1a;加载第N1周的.txt文件&#xff0c;使用Embeddingbag与Embedding完成词嵌入 第N1周的.txt文件的名称为“任务文件.txt”&#xff0c;内容为&#xff1a; 比较直观的编码方式是采用上…...

C++高精度减法

高精度减法其实跟加法差不多&#xff0c;首先就是需要逆序存入整数数组&#xff0c;其次就是做运算&#xff0c;最后就是删除前导0逆序输出。 不过在做高精度减法需要考虑一下两个数的关系是有三种的&#xff0c;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是一个开源的高性能反向代理和负载均衡器&#xff0c;主要用于‌TCP和‌HTTP流量管理。 功能和特点&#xff1a;haproxy能够处理大量的并发连接&#xff0c;支持TCP和HTTP协议&#xff0c;具有高可用性和负载均衡功能。它特别适用于需要处理大量流量的网站&am…...

K8S系列——一、Ubuntu上安装Helm

在使用K8S搭建集群服务时&#xff0c;有时候需要用到Helm&#xff08;一个用于Kubernetes应用管理的工具&#xff09;&#xff0c;下面是在Ubuntu上安装Helm的过程。 1.更新系统软件包列表 sudo apt-get update2.安装必要的依赖项 sudo apt-get install apt-transport-https…...

排序: 插入\希尔\选择\归并\冒泡\快速\堆排序实现

1.排序的概念及应用 1.1概念 排序:所谓排序&#xff0c;就是一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 1.2运用 购物筛选排序&#xff1a; 1.3常见排序算法 2.实现常见的排序算法 int a[ {5,3,9,6,2,4,7,1,8}; 2…...

OpenCV图像处理——按最小外接矩形剪切图像处理ROI后映射回原图像

引言 在图像处理过程中&#xff0c;提取感兴趣区域&#xff08;ROI&#xff09;并在其上进行处理后&#xff0c;往往需要将处理后的结果映射回原图像。这一步通常涉及以下几个步骤&#xff1a; 找到最小外接矩形&#xff1a;使用 cv::boundingRect 或 cv::minAreaRect 提取感兴…...

Linux中以单容器部署Nginx+ASP.NET Core

强烈推荐在生产环境中使用反向代理服务器转发请求到Kestrel Http服务器&#xff0c;本文将会实践将Nginx --->ASP.NET Core 部署架构容器化的过程。 Nginx->ASP.NET Coe部署架构容器化 在Docker中部署Nginx--->ASP.NETCore 有两种选择&#xff0c; 第一种是在单容器…...

【秋招笔试】8.11大疆秋招(第三套)-三语言题解

🍭 大家好这里是 春秋招笔试突围,一起备战大厂笔试 💻 ACM金牌团队🏅️ | 多次AK大厂笔试 | 编程一对一辅导 ✨ 本系列打算持续跟新 春秋招笔试题 👏 感谢大家的订阅➕ 和 喜欢💗 和 手里的小花花🌸 ✨ 笔试合集传送们 -> 🧷春秋招笔试合集 🍒 本专栏已收…...

标题:打造编程学习的知识宝库:高效笔记记录与整理

标题&#xff1a;打造编程学习的知识宝库&#xff1a;高效笔记记录与整理 在编程学习的征途中&#xff0c;有效的笔记记录和整理技巧对于掌握和回顾知识点至关重要。本文将从笔记工具选择、笔记结构设计、以及实践与复习策略三个方面&#xff0c;探讨如何高效地记录并整理编程…...

【Rust光年纪】Rust 官方提供的关键工具概览:代码检查、格式化和依赖管理

提升 Rust 项目质量和安全性&#xff1a;掌握官方工具的核心功能和使用方法 前言 Rust 作为一种系统编程语言&#xff0c;拥有强大的性能和内存安全特性。然而&#xff0c;随着项目规模增长&#xff0c;代码检查、格式化和依赖管理等工作变得更加重要。因此&#xff0c;Rust …...

【Python学习-UI界面】PyQt5 小部件8-QSlider 数值滑动

样式如下: QSlider 类对象为用户提供一个沟槽&#xff0c;可以在其上移动一个手柄。 它是一个经典的小部件&#xff0c;用于控制有界值。 手柄在沟槽上的位置相当于控件的下限和上限之间的整数。 常用方法如下&#xff1a; 序号方法描述1setMinimum设置滑块的最小值2setMax…...

19c补丁后oracle属主变化,导致不能识别磁盘组

补丁后服务器重启&#xff0c;数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后&#xff0c;存在与用户组权限相关的问题。具体表现为&#xff0c;Oracle 实例的运行用户&#xff08;oracle&#xff09;和集…...

STM32+rt-thread判断是否联网

一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

视频字幕质量评估的大规模细粒度基准

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用&#xff0c;因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型&#xff08;VLMs&#xff09;在字幕生成方面…...

【JavaWeb】Docker项目部署

引言 之前学习了Linux操作系统的常见命令&#xff0c;在Linux上安装软件&#xff0c;以及如何在Linux上部署一个单体项目&#xff0c;大多数同学都会有相同的感受&#xff0c;那就是麻烦。 核心体现在三点&#xff1a; 命令太多了&#xff0c;记不住 软件安装包名字复杂&…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)

前言&#xff1a; 最近在做行为检测相关的模型&#xff0c;用的是时空图卷积网络&#xff08;STGCN&#xff09;&#xff0c;但原有kinetic-400数据集数据质量较低&#xff0c;需要进行细粒度的标注&#xff0c;同时粗略搜了下已有开源工具基本都集中于图像分割这块&#xff0c…...

从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践

作者&#xff1a;吴岐诗&#xff0c;杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言&#xff1a;融合数据湖与数仓的创新之路 在数字金融时代&#xff0c;数据已成为金融机构的核心竞争力。杭银消费金…...

Linux系统部署KES

1、安装准备 1.版本说明V008R006C009B0014 V008&#xff1a;是version产品的大版本。 R006&#xff1a;是release产品特性版本。 C009&#xff1a;是通用版 B0014&#xff1a;是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存&#xff1a;1GB 以上 硬盘&#xf…...

破解路内监管盲区:免布线低位视频桩重塑停车管理新标准

城市路内停车管理常因行道树遮挡、高位设备盲区等问题&#xff0c;导致车牌识别率低、逃费率高&#xff0c;传统模式在复杂路段束手无策。免布线低位视频桩凭借超低视角部署与智能算法&#xff0c;正成为破局关键。该设备安装于车位侧方0.5-0.7米高度&#xff0c;直接规避树枝遮…...

uniapp 小程序 学习(一)

利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 &#xff1a;开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置&#xff0c;将微信开发者工具放入到Hbuilder中&#xff0c; 打开后出现 如下 bug 解…...

小木的算法日记-多叉树的递归/层序遍历

&#x1f332; 从二叉树到森林&#xff1a;一文彻底搞懂多叉树遍历的艺术 &#x1f680; 引言 你好&#xff0c;未来的算法大神&#xff01; 在数据结构的世界里&#xff0c;“树”无疑是最核心、最迷人的概念之一。我们中的大多数人都是从 二叉树 开始入门的&#xff0c;它…...