当前位置: 首页 > 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…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

MySQL中【正则表达式】用法

MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现&#xff08;两者等价&#xff09;&#xff0c;用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例&#xff1a; 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

06 Deep learning神经网络编程基础 激活函数 --吴恩达

深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

基于Java+MySQL实现(GUI)客户管理系统

客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息&#xff0c;对客户进行统一管理&#xff0c;可以把所有客户信息录入系统&#xff0c;进行维护和统计功能。可通过文件的方式保存相关录入数据&#xff0c;对…...