考核:QTableWidget开发[折叠/展开单元格QTableWidgetItem]

news2024/11/15 4:49:08

目录

  • 效果
  • 要求
    • 一、功能概述
    • 二、功能
    • 三、关系
      • FATable 表
      • NTable 表
      • CTable 表
  • 实现
    • infos.h
    • main.cpp
    • complextablewidget.h
    • complextablewidget.cpp
    • schemedialog.h
    • schemedialog.cpp
  • 源码
  • 模糊知识点

效果

在这里插入图片描述

要求

一、功能概述

在这里插入图片描述

二、功能

在这里插入图片描述

三、关系

在这里插入图片描述

FATable 表

CREATE TABLE fatable (idFA INTEGER,nameId TEXT,equipId TEXT,equipNum INTEGER);

在这里插入图片描述

idFAnameIdequipIdequipNum
1A100190014
1A100190031
2A100190026
2A100190208
1B2001900210
1B200190041
2B200190064
2B200190082
2B200190104
1A1002900216
2A100290031
3A1002902016
3A100290108
1B2002900218
2B200290064
2B200290084
2B200290108
3B200290031
3B200290041

NTable 表

CREATE TABLE nTable (name VARCHAR(100),nameId VARCHAR(10),classify INT);

在这里插入图片描述

namenameIdclassify
奥迪A6LA10012
宝马X7A10022
迈巴赫S600B20013
劳斯莱斯-库里南B20023
Dynaudio丹拿90014
柏林之声90024
前天窗90035
后天窗90045
前排气囊90066
后排气囊90086
侧面气囊90102
空调口90202

CTable 表

CREATE TABLE cTable (classify INT,className VARCHAR(100));

在这里插入图片描述

classifyclassName
1B级车中型车
2C级车中大型车
3S级车顶级豪华车
4音响
5天窗
6气囊
7空调

实现

infos.h


#ifndef INFOS_H
#define INFOS_H
#include<QString>
#include<QVector>
struct FATable {
    int idFA;               //方案ID
    QString nameId;         //名称ID
    QString equipId;        //装备ID
    int equipNum;           //装备数量
};
inline QVector<FATable> faTable = {
    {1, "A1001", "9001",4},
    {1, "A1001", "9003",1},
    {2, "A1001", "9002",6},
    {2, "A1001", "9020",8},
    {1, "B2001", "9002",10},
    {1, "B2001", "9004",1},
    {2, "B2001", "9006",4},
    {2, "B2001", "9008",2},
    {2, "B2001", "9010",4},
    {1, "A1002", "9002",16},
    {2, "A1002", "9003",1},
    {3, "A1002", "9020",16},
    {3, "A1002", "9010",8},
    {1, "B2002", "9002",18},
    {2, "B2002", "9006",4},
    {2, "B2002", "9008",4},
    {2, "B2002", "9010",8},
    {3, "B2002", "9003",1},
    {3, "B2002", "9004",1},
    };

struct NTable {
    QString name;           //装备名称
    QString nameId;         //装备ID
    int classify;           //分类ID
};
inline QVector<NTable> nTable = {
    {"奥迪A6L", "A1001", 2},
	{"宝马X7", "A1002", 2},
	{"迈巴赫S600", "B2001",3},
	{"劳斯莱斯-库里南", "B2002",3},
	{"Dynaudio丹拿", "9001", 4},
	{"柏林之声", "9002",4},
	{"前天窗", "9003",5},
	{"后天窗", "9004", 5},
	{"前排气囊", "9006", 6},
	{"后排气囊", "9008", 6},
	{"侧面气囊", "9010", 2},
	{"空调口", "9020", 2},
};
struct CTable {
    int classify;           //分类ID
    QString className;      //分类名称
};
inline QVector<CTable> cTable = {
    {1, "B级车中型车"},
    {2, "C级车中大型车"},
    {3, "S级车顶级豪华车"},
    {4, "音响"},
    {5, "天窗"},
    {6, "气囊"},
    {7, "空调"}
};
#endif // INFOS_H

main.cpp

ComplexTableWidget w;
w.show();

complextablewidget.h

#ifndef COMPLEXTABLEWIDGET_H
#define COMPLEXTABLEWIDGET_H
#include <QDialog>
class SchemeDialog;
QT_BEGIN_NAMESPACE
namespace Ui { class ComplexTableWidget; }
QT_END_NAMESPACE
class ComplexTableWidget : public QDialog

{
    Q_OBJECT

public:
    ComplexTableWidget(QWidget *parent = nullptr);
    ~ComplexTableWidget();

private:
    Ui::ComplexTableWidget *ui;
    void initUI();
    QStringList m_schemeItems;
private slots:
    void on_searchBtn_clicked();
};
#endif // COMPLEXTABLEWIDGET_H

complextablewidget.cpp

#include "complextablewidget.h"
#include "ui_complextablewidget.h"
#include<QPushButton>
#include<QSplitter>
#include<QLabel>
#include<QDebug>
#include "schemedialog.h"
#include "infos.h"
#include<QDebug>
ComplexTableWidget::ComplexTableWidget(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::ComplexTableWidget)
{
    ui->setupUi(this);
    initUI();
}

ComplexTableWidget::~ComplexTableWidget()
{
    delete ui;
}

void ComplexTableWidget::initUI()
{
    setWindowFlags(Qt::Dialog|Qt::WindowMaximizeButtonHint|Qt::WindowCloseButtonHint);
    ui->searchLEdit->setPlaceholderText("请输入名称");
    ui->tableWidget->horizontalHeader()->setVisible(false);
    ui->tableWidget->horizontalHeader()->setSelectionBehavior(QAbstractItemView::SelectRows);   // 选择行为:行
    ui->tableWidget->horizontalHeader()->setSelectionMode(QAbstractItemView::SingleSelection);  // 选择模式:单选
    ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);

    ui->tableWidget->setColumnCount(1);
    ui->tableWidget->setRowCount(0);
    m_schemeItems.clear();
    QMap<QString,QList<FATable>> nameIdMap;
    for (auto &it:faTable) {
        nameIdMap[it.nameId].append(it);
    }
    QMap<QString,QString> idToNameMap;
    for (auto &it:nTable) {
        idToNameMap.insert(it.nameId,it.name);
    }

    for (auto &namekey:nameIdMap.keys())
    {
        m_schemeItems.append(idToNameMap.value(namekey));
        int row=ui->tableWidget->rowCount();

        ui->tableWidget->insertRow(row);

        auto *schemeDialog=new SchemeDialog(namekey, nameIdMap.value(namekey));
        // 将父级对话框设置为单元格的组件
        ui->tableWidget->setCellWidget(row, 0, schemeDialog);
        // 设置单元格的行高以适应内容
        ui->tableWidget->resizeRowsToContents();

        connect(schemeDialog, &SchemeDialog::isFoldSignal, [this]() {
            qDebug()<<"点击";
            // 设置单元格的行高以适应内容
            ui->tableWidget->resizeRowsToContents();
        });
    }

}

void ComplexTableWidget::on_searchBtn_clicked()
{
    QString search = ui->searchLEdit->text();
    if(search.isEmpty())
        return;
    int row = m_schemeItems.indexOf(search);
    if(row==-1)
        return;

    auto item=static_cast<SchemeDialog*>(ui->tableWidget->cellWidget(row,0));
    item->setFoldView(false);
    ui->tableWidget->setCurrentCell(row,0);
    // 设置单元格的行高以适应内容
    ui->tableWidget->resizeRowsToContents();
}

schemedialog.h

#ifndef SCHEMEDIALOG_H
#define SCHEMEDIALOG_H

#include <QDialog>
#include "infos.h"
namespace Ui {
class SchemeDialog;
}

class SchemeDialog : public QDialog
{
    Q_OBJECT

public:
    explicit SchemeDialog(QWidget *parent = nullptr);
    SchemeDialog(const QString &name,const QList<FATable> currNameInfos,QWidget *parent = nullptr);
    ~SchemeDialog();

    void initUI();
    void updataTabel();
    void updataFoldBtnIcon(bool);
    void setFoldView(bool);
signals:
    void isFoldSignal(bool);

private slots:
    void on_foldBtn_clicked();

private:
    Ui::SchemeDialog *ui;
    const QString m_name;
    const QList<FATable> m_currNameInfos;
};
#endif // SCHEMEDIALOG_H

schemedialog.cpp

#include "schemedialog.h"
#include "ui_schemedialog.h"

#include<QDebug>
namespace{
    enum EMountCol{
                MountID=0,      //方案ID
                MountSum,       //挂载总量
                MountConfig     //挂载配置
    };
    QVariantMap idToNameMap;    //通过装备ID获取装备名称
}
SchemeDialog::SchemeDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::SchemeDialog)
{
    ui->setupUi(this);
}

SchemeDialog::SchemeDialog(const QString &name, const QList<FATable> currNameInfos, QWidget *parent)
    :QDialog(parent),
    ui(new Ui::SchemeDialog),
    m_name(name),
    m_currNameInfos(currNameInfos)
{
    ui->setupUi(this);
    initUI();
    updataTabel();
}

SchemeDialog::~SchemeDialog()
{
    delete ui;
}

void SchemeDialog::initUI()
{
    setWindowFlags(Qt::FramelessWindowHint);  // 设置无边框样式
    ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
    ui->tableWidget->horizontalHeader()->setSelectionBehavior(QAbstractItemView::SelectRows);   // 选择行为:行
    ui->tableWidget->horizontalHeader()->setSelectionMode(QAbstractItemView::SingleSelection);  // 选择模式:单选
    ui->tableWidget->horizontalHeader()->setStretchLastSection(true);
    ui->tableWidget->verticalHeader()->setVisible(false);

    idToNameMap.clear();
    QVariantMap idToClassifyMap;
    for (auto &var:nTable) {
        idToNameMap.insert(var.nameId,var.name);
        idToClassifyMap.insert(var.nameId,var.classify);
    }
    ui->nameLabel->setText(idToNameMap.value(m_name).toString());

    QMap<int,QString> idKeyMap;
    for (auto &var:cTable) {
        idKeyMap.insert(var.classify,var.className);
    }
    ui->typeLabel->setText(idKeyMap.value(idToClassifyMap[m_name].toInt()));
}

void SchemeDialog::updataTabel()
{
    ui->tableWidget->setRowCount(0);
    QMap<int,int> mountSumNumMap;
    QMap<int,QMap<QString,int>> mountNumMap;
    for (auto &it:m_currNameInfos) {
        mountSumNumMap[it.idFA]+=it.equipNum;
        mountNumMap[it.idFA][it.equipId]=it.equipNum;
    }

    for (auto &faId:mountSumNumMap.keys()) {
        int row=ui->tableWidget->rowCount();
        ui->tableWidget->insertRow(row);
        ui->tableWidget->setItem(row,EMountCol::MountID,new QTableWidgetItem(QString::number(faId)));
        ui->tableWidget->setItem(row,EMountCol::MountSum,new QTableWidgetItem(QString::number(mountSumNumMap[faId])));
        QStringList mountConfig;
        for (auto &equipId:mountNumMap[faId].keys()) {
            mountConfig.append(QString("%1(%2个)").arg(idToNameMap[equipId].toString()).arg(mountNumMap[faId][equipId]));
        }
        ui->tableWidget->setItem(row,EMountCol::MountConfig,\
                                new QTableWidgetItem(mountConfig.join("+")));
    }
}

void SchemeDialog::updataFoldBtnIcon(bool isFold)
{
    if(isFold)
        ui->foldBtn->setText("□");
    else
        ui->foldBtn->setText("-");
}

void SchemeDialog::setFoldView(bool isFold)
{
    ui->groupBox->setVisible(!isFold);
    updataFoldBtnIcon(isFold);
}

void SchemeDialog::on_foldBtn_clicked()
{
    bool isFold = ui->groupBox->isVisible();
    ui->groupBox->setVisible(!isFold);
    emit isFoldSignal(isFold);
    updataFoldBtnIcon(isFold);
}

源码

Gitee:03ComplexTableWidget

模糊知识点

  1. 通过使用 inline 关键字,我们告诉编译器,在每个源文件中只需要保留一个 cTable 的实例,这样就避免了重定义错误

也理解为

inline关键字的作用类似于函数内联,它告诉编译器可以在多个源文件中共享同一个变量实例。

在infos.h中使用inline定义QVector<CTable> cTable是为了确保在多个源文件中包含该头文件时,对cTable的定义不会引起重定义错误

  1. void QTableView::resizeRowsToContents() 方法可以根据QTableWidgetItem中的文本内容自动调整行高,以确保所有的文本都能够完整显示
  • 当你在单元格中使用QTableWidgetItem时,它会自动计算文本的大小并将其显示在单元格中。
  • 调用resizeRowsToContents()方法后,表格会遍历每一行,并根据每个单元格中的文本内容的大小来自动调整行高。

如果单元格是QWidget,resizeRowsToContents()会根据内容的最小高度自动设置单元格的行高

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/758064.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

UE4从零开始制作数字孪生道路监测平台

UE4从零开始制作数字孪生道路监测平台 UE4集成Cesium for Unreal和WebSocket&#xff0c;后端使用NodeJs搭建服务器进行数据模拟和真实数据实时转发。 1&#xff1a;新建UE4项目并集成Cesium for Unreal Cesium for UE4插件解锁了虚幻引擎中的3D地理空间生态系统。通过将高精…

基于FPGA的softmax函数优化及实现

文章目录 前言优化方案测试数据产生及Matlab结果处理流程工程说明功耗与面积标准softmax函数功耗与面积总结前言 FPGA异构计算是一个趋势,在AI推理、深度学习中广泛使用FPGA进行加速,减小系统延迟。而AI推理中有一个组件被广泛使用,各种网络模型中都有其身影,那就是激活函…

【雕爷学编程】Arduino动手做(152)---BMI160 六轴陀螺仪模块2

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

走进Linux世界【三、Linux文件与路径】

第三章 Linux文件与路径 1、文件结构 ​ Windows和Linux文件系统区别 ​ 在windows平台下&#xff0c;打开“此电脑”&#xff0c;我们可以看到盘符分区 ​ 每个驱动器都有自己的根目录结构&#xff0c;这样形成了多个树并列的情形 ​ 但是在 Linux 下&#xff0c;我们是看…

创建和分析二维桁架和梁结构研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

03_008内存映射原理_虚拟内存区域vm_area_struct详解,和mmap系统钓调用完全分析

前言 上一个记录中的 虚拟地址里的虚拟内存区域没有说的很完全 这次补充一下 同时记录一些 物理地址空间 内存映射原理 最后直接通过进程使用函数完成虚拟空间到物理空间的映射 物理地址空间 物理地址是处理器在系统总线上看到的地址。使用RISC的处理器通常只实现一个物理地…

递归函数(详解+实战)

目录 递归函数介绍 递归函数的作用 案例&#xff1a;实现10以内阶乘 递归思想 递归的编写 斐波那契数列(实战) 循环实现 递归实现 递归函数介绍 递归函数是指在函数的定义中调用函数本身的过程。递归函数可以用于解决那些可以通过将大问题拆分为更小的相似子问题来解决的…

窗口看门狗 WWDG

窗口看门狗介绍 Q: 什么是窗口看门狗&#xff1f; A: 窗口看门狗用于监测单片机程序运行时效是否精准&#xff0c;主要检测软件异常(独立看门狗检测的是硬件异常)&#xff0c;一般用于需要精准检测&#xff08;独立看门狗不太精准&#xff09;程序运行时间的场合。 窗口看门狗…

MySQL数据库操作篇3(聚合函数分组查询)

通过MySQL提供的聚合函数&#xff0c;可以很方便的进行一些计算来辅助查询&#xff0c;所谓聚合函数就是将表中的数据统计后进行的某种处理 分组查询可以理解成将一张表按照某个属性分成多张表&#xff0c;属性值相同的在一张表里 比如说学生表&#xff0c;按照性别这个属性分组…

java+大数据实战 短链项目

一.前言 1.1课程大致包含技术 首先选这套课的目的是 包含了我所学的大部分技术 比如springboot ssm redis kafka flink clickhouse 等 1.2 外界客观原因 就业环境一般 目前来看暂时还没但是有后续潜在的毕业 或者 离职 1.3技术追求 个人的技术追求暂时是在技术总监 技术…

vue3功能实现

在vue2中&#xff0c;要实现一些方法&#xff08;增删改查&#xff09;一般都是写在一起的。如下图所示&#xff1a; 但是在vue3中&#xff0c;实现一个方法需要用到很多文件。 方法定义方法如下&#xff1a; export function classSign(phone: string) {return sign_reques…

TypeScript基础篇 - 类型的思考方式

目录 重新认识&#xff1a;什么是类型&#xff1f; 类型是人类的思考方式 类型是错误检查的利器 总结&#xff1a;为什么我们用TS&#xff1f; 一张ai生成图~ 重新认识&#xff1a;什么是类型&#xff1f; 汽车可以跑怎么理解&#xff1f; car.run() 【面向对象】car imp…

【雕爷学编程】Arduino动手做(06)---KY-038声音传感器模块3

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

微服务架构Ribbon与OpenFeign的使用 【快速入门】

一、实现负载均衡&#x1f349; 1.什么是负载均衡&#x1f95d; 通俗的讲&#xff0c; 负载均衡就是将负载&#xff08;工作任务&#xff0c;访问请求&#xff09;进行分摊到多个操作单元&#xff08;服务器,组件&#xff09;上进行执行。 根据负载均衡发生位置的不同,一般分…

Terraform(一)

IaC 自动化配置与编排神器 - Terraform 1. 相关概念1.1 什么是 IaCIaC 的两种实现方式IaC 的好处IaC 优点IaC 工具为什么 IaC 对 DevOps 很重要&#xff1f; 1.2 什么是 Terraform1.3 Terraform 的主要特性1.4 Terraform 架构1.5 Terraform 核心概念1.6 Terraform 生命周期1.7 …

高等数学❤️第一章~第二节~极限❤️无穷小量与无穷大量~无穷小量概念及其性质与比较详解

【精讲】高等数学中的无穷小量概念及其性质与比较 博主&#xff1a;命运之光的主页 专栏&#xff1a;高等数学 目录 【精讲】高等数学中的无穷小量概念及其性质与比较 导言 一、无穷小量的概念 二、无穷小量的性质 三、无穷小量的比较 四、无穷小量的应用 必需记忆知识点…

【C++刷题集】-- day4

目录 选择题​​​​​​​ 单选 编程题 计算糖果⭐ 【题目解析】 【解题思路】 进制转换⭐​​​​​​​ 【题目解析】 【解题思路】 选择题 单选 1、 有以下程序 #include<iostream> #include<cstdio> using namespace std; int main() {int m 0123, n 123…

(文章复现)售电市场环境下电力用户选择售电公司行为研究(附matlab代码)

参考文献&#xff1a; [1]孙云涛,宋依群,姚良忠等.售电市场环境下电力用户选择售电公司行为研究[J].电网技术,2018,42(04):1124-1131. 1.基本原理 1 .1演化博弈 与古典博弈理论相比较&#xff0c;演化博弈假设参与人是有限理性的&#xff0c;参与人会根据自己和他人的经验选…

【前端】网页开发精讲与实战 CSS Day 4

&#x1f680;Write In Front&#x1f680; &#x1f4dd;个人主页&#xff1a;令夏二十三 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd; &#x1f4e3;系列专栏&#xff1a;前端 &#x1f4ac;总结&#xff1a;希望你看完之后&#xff0c;能对你有…