qt的model view 使用示范

news2024/11/23 11:40:00

在这里插入图片描述

首先在ui界面拖一个tableView
ui->tableView->setModel(mission_model);

然后设置model的qss,并用view绑定model

void SettingWidget::init_missionmodel(QString plane_type, QString mission_name)
{
    if(mission_model)
        delete mission_model;
    mission_model = new MissionModel(plane_type, mission_name, this);
    connect(mission_model, SIGNAL(missionFollow_send(QVariant, QVariant)), this, SLOT(getMissionFollow(QVariant, QVariant)));
    connect(mission_model, SIGNAL(namePlate_show(QVariant)), this, SLOT(getNamePlate(QVariant)));
    ui->tableView->setModel(mission_model);
    int row_count = mission_model->rowCount();
    for (int i = 0; i < row_count; i++)
    {
        QModelIndex index = mission_model->index(i, 4);
        QPushButton *button = static_cast<QPushButton*>(index.internalPointer());
        ui->tableView->setIndexWidget(index, button);
    }

    ui->tableView->horizontalHeader()->resizeSection(0,80);
    ui->tableView->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);
    ui->tableView->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Stretch);
    ui->tableView->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Stretch);
    ui->tableView->horizontalHeader()->setSectionResizeMode(4, QHeaderView::Stretch);

    //ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
    ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection);
    ui->tableView->setContextMenuPolicy(Qt::CustomContextMenu);
    ui->tableView->verticalHeader()->hide();
  //  ui->tableView->horizontalHeader()->setStyleSheet("QHeaderView::section{background:#3a3e46;color: white;}");
}

MissionModel.h

#ifndef MISSIONMODEL_H
#define MISSIONMODEL_H

#include <QAbstractTableModel>
#include <QJsonObject>
#include <QJsonArray>
#include <QPushButton>
#include <QMap>


class MissionModel : public QAbstractTableModel
{
    Q_OBJECT
public:
    MissionModel(QString plane_name_t, QString mission_name, QObject *parent = nullptr);
    virtual ~MissionModel() override;

    // Header:
    QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;

    // Basic functionality:
    int rowCount(const QModelIndex &parent = QModelIndex()) const override;
    int columnCount(const QModelIndex &parent = QModelIndex()) const override;

    QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;

    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;

    bool setData(const QModelIndex &index, const QVariant &value, int role) override;

    void refresh();

    Qt::ItemFlags flags(const QModelIndex & index) const override ;

    QJsonObject getItemData(int index);

    void init_data();

signals:
    void missionFollow_send(QVariant missionName, QVariant missionColor);
    void namePlate_show(QVariant missionName);

private:
    QList<QString> headtitle;
    QJsonArray dataList;

    QMap<int,QPushButton* > color_buttons;

    QString plane_name;
    QString mission_name;
    QString file_name;
};

#endif // MISSIONMODEL_H

MissionModel.cpp

#include "missionmodel.h"

#include <QCoreApplication>
#include <QFile>
#include <QJsonArray>
#include <QMessageBox>
#include <QColorDialog>

#include "global.h"
#include "./ui/util/jsontool.h"

MissionModel::MissionModel(QString plane_name_t, QString mission_name_t, QObject *parent)
    : plane_name(plane_name_t), mission_name(mission_name_t), QAbstractTableModel(parent)
{
    headtitle<< QStringLiteral("序号") << QStringLiteral("项目名称") << QStringLiteral("实时关注") << QStringLiteral("铭牌显示") << QStringLiteral("颜色");

    init_data();
}

MissionModel::~MissionModel()
{
    foreach (QPushButton* button, color_buttons.values()) {
        delete button;
    }
    color_buttons.clear();
}

QVariant MissionModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    switch(role){
    case Qt::DisplayRole:
    {
        if (orientation == Qt::Horizontal) {
            return headtitle[section];
        }
        break;
    }
//    case Qt::FontRole:
//    {
//        QFont boldFont;
//        boldFont.setBold(true);
//        boldFont.setPixelSize(14);
//        return boldFont;
//    }
    case Qt::TextAlignmentRole:
        return Qt::AlignLeft + Qt::AlignVCenter;
        break;
    }
    return QVariant();
}

int MissionModel::rowCount(const QModelIndex &parent) const
{
    return dataList.size();
}

int MissionModel::columnCount(const QModelIndex &parent) const
{
    return headtitle.size();
}


//在第4列放按钮
QModelIndex MissionModel::index(int row, int column, const QModelIndex &parent) const
{

    if (column == 4)
    {
        return createIndex(row, column, color_buttons[row]);
    }
    else
        return QAbstractTableModel::index(row, column, parent);
}
//在第 2,3 列放checkbox
Qt::ItemFlags MissionModel::flags(const QModelIndex &index) const
{
    if (index.column() == 2 || index.column() == 3)
        return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;

    return QAbstractTableModel::flags(index);
}

//这里负责把数据显示到界面对应单元格
重点
setdata()的调用次数=row * col *31(枚举数)

有多少行就调用多少次。每一行有多少列就调用多少次。对每一个单元格的枚举调用多少次

如下图针对每个单元格的31哥枚举会调用31次data()
比如背景颜色,文本居中,文本颜色,显示内容,如果是checkbox,那么选中状态bool

 Qt::TextAlignmentRole: Qt::DisplayRole: Qt::CheckStateRole:
  enum ItemDataRole {
        DisplayRole = 0,
        DecorationRole = 1,
        EditRole = 2,
        ToolTipRole = 3,
        StatusTipRole = 4,
        WhatsThisRole = 5,
        // Metadata
        FontRole = 6,
        TextAlignmentRole = 7,
        BackgroundRole = 8,
        ForegroundRole = 9,
#if QT_DEPRECATED_SINCE(5, 13) // ### Qt 6: remove me
        BackgroundColorRole Q_DECL_ENUMERATOR_DEPRECATED = BackgroundRole,
        TextColorRole Q_DECL_ENUMERATOR_DEPRECATED = ForegroundRole,
#endif
        CheckStateRole = 10,
        // Accessibility
        AccessibleTextRole = 11,
        AccessibleDescriptionRole = 12,
        // More general purpose
        SizeHintRole = 13,
        InitialSortOrderRole = 14,
        // Internal UiLib roles. Start worrying when public roles go that high.
        DisplayPropertyRole = 27,
        DecorationPropertyRole = 28,
        ToolTipPropertyRole = 29,
        StatusTipPropertyRole = 30,
        WhatsThisPropertyRole = 31,
        // Reserved
        UserRole = 0x0100
    };

QVariant MissionModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();

    int row = index.row();
    int col = index.column();
    QJsonObject obj = dataList.at(row).toObject();

    switch(role){
    case Qt::DisplayRole:
    {
        switch (col) {
        case 0:
            return row + 1;
        case 1:
            return obj[headtitle.at(1)].toString();
        case 2:
            return obj[headtitle.at(2)].toString();
        case 3:
            return obj[headtitle.at(3)].toString();
        case 4:
        {
            QPushButton *button = static_cast<QPushButton*>(index.internalPointer());
            button->setText(obj[headtitle.at(4)].toString());
      //      button->setStyleSheet(QString("background-color: %1").arg(obj[headtitle.at(4)].toString()));
            return obj[headtitle.at(4)].toString();
        }
        default:
            break;
        }
    }
        break;
    case Qt::TextAlignmentRole:
        {
            if(col == 0)
                return Qt::AlignCenter;
        }
        return Qt::AlignLeft + Qt::AlignVCenter;
        break;
    case Qt::ForegroundRole:
           switch (col) {
           case 1:
               //return  info.isLive? QVariant(QColor("#7ebdfd")):QVariant(QColor("#ee6666"));
               break;
           default:
               break;
           }
        break;
    case  Qt::CheckStateRole:
    {
        QJsonObject obj = dataList.at(row).toObject();
        if (index.column() == 2)
        {
            return obj[headtitle.at(2)].toBool() == true ? Qt::Checked : Qt::Unchecked;
        }
        else if (index.column() == 3)
        {
            return obj[headtitle.at(3)].toBool() == true ? Qt::Checked : Qt::Unchecked;
        }
    }
    }

    return QVariant();
}

bool MissionModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if(!index.isValid())
        return false;
    int row = index.row();
    int col = index.column();
    QModelIndex m_index_name = this->index(row,1);
    QModelIndex m_index_color = this->index(row,4);
    QVariant missionName = this->data(m_index_name);
    QVariant missionColor = this->data(m_index_color);
//    if (role == Qt::CheckStateRole && (col == 2 || col == 3) )
//    {
//        QJsonObject obj = dataList[row].toObject();
//        obj[headtitle.at(col)] = value == Qt::Checked;
//        dataList[row] = obj;

//        if( !JsonTool::save_json_file<QJsonArray>(file_name, dataList) )
//        {
//            QMessageBox::information( nullptr, QStringLiteral("修改失败"), QStringLiteral("修改失败"));
//        }
//    }
    if (role == Qt::CheckStateRole && col == 2 )
    {
        QJsonObject obj = dataList[row].toObject();
        obj[headtitle.at(col)] = value == Qt::Checked;
        dataList[row] = obj;

        if(obj[headtitle.at(2)].toBool() == true)
        {
            emit missionFollow_send(missionName, missionColor);
            return true;
        }
        if( !JsonTool::save_json_file<QJsonArray>(file_name, dataList) )
        {
            QMessageBox::information( nullptr, QStringLiteral("修改失败"), QStringLiteral("修改失败"));
        }
    }
    else if (role == Qt::CheckStateRole && col == 3 )
    {
        QJsonObject obj = dataList[row].toObject();
        obj[headtitle.at(col)] = value == Qt::Checked;
        dataList[row] = obj;

        if(obj[headtitle.at(2)].toBool() == true)
        {
            emit namePlate_show(missionName);
            return true;
        }
        if( !JsonTool::save_json_file<QJsonArray>(file_name, dataList) )
        {
            QMessageBox::information( nullptr, QStringLiteral("修改失败"), QStringLiteral("修改失败"));
        }
    }
    return true;
}

void MissionModel::refresh()
{
    beginResetModel();
    //...
    endResetModel();
}

//这个是我自己写的
QJsonObject MissionModel::getItemData(int index)
{
    return dataList.at(index).toObject();
}


void MissionModel::init_data()
{
    file_name = QString("%1/config/fc_config/%2_%3.json").arg(QCoreApplication::applicationDirPath()).arg(plane_name).arg(mission_name);

    if(QFile::exists(file_name))
    {
        QJsonArray json_array = JsonTool::load_jsonarray_file(file_name);
        //dataList. .clear();
        for(int i = 0; i < json_array.size(); i++)
        {
            dataList.append(json_array.at(i).toObject());
        }
    }
    else
    {
        //dataList.clear();

        QString tmp_file_name = QString("%1/config/fc_config/%2.json").arg(QCoreApplication::applicationDirPath()).arg(plane_name);        
        QJsonObject obj = JsonTool::load_json_file(tmp_file_name);

        QStringList keys = obj.keys();
        if(keys.empty())
        {
            qWarning()<<"read a empty obj: "<<tmp_file_name<<endl;
            return;
        }

        QJsonArray json_array;
        foreach (QString key, keys)
        {
            QJsonObject item;
            item.insert(QStringLiteral("项目名称"), key);
            item.insert(QStringLiteral("实时关注"), false);
            item.insert(QStringLiteral("铭牌显示"), false);
            item.insert(QStringLiteral("颜色"), "#ffffff");

            json_array.append(item);
            dataList.append(item);
        }

        JsonTool::save_json_file<QJsonArray>(file_name, json_array);
    }

    color_buttons.clear();
    for(int i = 0; i<dataList.size(); i++)
    {
        QPushButton* button_p = new QPushButton();
        connect(button_p, &QPushButton::clicked, this, [=](){
            QColor color = QColorDialog::getColor();
            if (color.isValid()) {
                QPushButton *button = qobject_cast<QPushButton *>(sender());
                if (button)
                {
           //         button->setStyleSheet(QString("background-color: %1").arg(color.name()));

                    QJsonObject obj = dataList[i].toObject();
                    obj[headtitle.at(4)] = color.name();
                    dataList[i] = obj;

                    if( !JsonTool::save_json_file<QJsonArray>(file_name, dataList) )
                    {
                        QMessageBox::information( nullptr, QStringLiteral("修改失败"), QStringLiteral("修改失败"));
                    }
                }
            }
        });
        color_buttons.insert(i, button_p);
    }
}

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

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

相关文章

《智能计算系统:从深度学习到大模型(第2版)》重磅上市!

大家好&#xff0c;我是herosunly。985院校硕士毕业&#xff0c;现担任算法研究员一职&#xff0c;热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名&#xff0c;CCF比赛第二名&#xff0c;科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的…

PINCE——Linux 原生游戏内存修改器,一款替代 Cheat Engine 的强大游戏修改器,Linux 游戏玩家必备神器!

PINCE——Linux 原生游戏内存修改器&#xff0c;一款替代 Cheat Engine 的强大游戏修改器&#xff0c;Linux 游戏玩家必备神器&#xff01; PINCE 是 GNU Project Debugger(GDB) 的前端/反向工程工具&#xff0c;常用作程序调试器&#xff0c;主要用于游戏领域&#xff0c;修改…

docker容器图形化管理之Portainer

docker容器轻量级图形页面管理之Portainer 1、查看portainer镜像 [rootlocalhost ~]# docker search portainer 2、下载portainer镜像 [rootlocalhost ~]# docker pull portainer/portainer #选择喜欢的portainer风格镜像下载 3、启动dockerui容器 [rootlocalhost ~]# doc…

京东物流开放平台对接云打印功能

这是京东开发文档的流程图&#xff0c;根据自己的需求分析&#xff0c;我选择的是接入方式一 这是接入方式一的流程图: 所有第一步我们先下载他的打印组件并安装&#xff1a;京东物流开放平台 第二步呢就是看你有没有自定义快递面单的需求&#xff0c;由于目前我没有特别的需…

录屏选区指南,优选3款支持区域录制的录屏软件!

在数字内容创作和分享的时代&#xff0c;录屏软件成为了游戏玩家、教育工作者和视频博主的重要工具。无论是想要捕捉精彩的游戏瞬间&#xff0c;还是制作教学视频&#xff0c;选择正确的录屏区域都是确保内容质量和观众体验的关键。然而&#xff0c;面对市面上众多的录屏软件&a…

HDFS回收站-删除策略详解

HDFS拥有回收站的功能,将某一段时间的删除的数据,放到指定路径(/user/{username}/.Trash),至少保留指定的时间,然后一起删除。 现实中发现回收站里有该删除的却没有删除,和回收站原理逻辑对不上。 以下从源码上看看到底是什么原因导致的。 背景 某HDFS集群指定数据保留…

Docusign Maestro:智能自动化,实现无缝协作,让签约更简单!

作为 Docusign IAM 引擎的核心部分&#xff0c;Maestro 能够帮助你自动化、定制并连接你的协议工作流程。你可以完全按照自己的需求&#xff0c;定制每一个流程细节。无论是什么类型的协议&#xff0c;Maestro 都能减少繁琐的手动操作&#xff0c;让最终用户更快、更轻松地完成…

springboot网上商品订单转手系统论文源码调试讲解

第2章 开发环境与技术 开发网上商品订单转手系统需要搭建编程的环境&#xff0c;也需要通过调查&#xff0c;对各个相关技术进行分析&#xff0c;选取适合本系统开发的技术与工具。 2.1 MYSQL数据库 题目确定了是一个应用程序之后&#xff0c;就开始按部就班的进行设计与分析…

7个超有意思的网站,值得收藏起来慢慢用

分享7个超有意思的网站&#xff0c;绝对让你意想不到&#xff01; 1、动漫捏脸 Picrew&#xff5c;つくってあそべる画像メーカー 一个超有趣的二次元动漫捏脸网站&#xff0c;你可以随意制作自己喜欢的各种动漫形象、头像等画作&#xff0c;搭配B站教程食用更佳哦~ 搭配教…

全场景 真利旧 强运维!麒麟信安打造县域自主创新云办公解决方案

近年来&#xff0c;国家正大力推进信息技术自主创新&#xff0c;减少对外依赖&#xff0c;并在关键行业加速推广和应用自研技术产品。现全国乡镇以上各级党政机关积极响应国家战略指引&#xff0c;全面实施自主创新办公系统建设升级。但在升级过程中&#xff0c;却因设备架构和…

4款AI 生成 PPT的工具,帮你赶上演示文稿的新趋势!

AI 生成 PPT 最大的优势就在于它能够帮助我们提高效率。如果我们自己制作的话就需要花费大量的时间去收集资料、构思布局、设计排版。而现在&#xff0c;有了AI工具&#xff0c;一切就迎刃而解&#xff0c;如果大家需要这样的工具&#xff0c;可以看看这4款。 1、笔灵办公 直通…

网络硬盘录像机NVR程序源码海思3520D NVR 安防监控智能升级运用方案

随着安防技术的不断发展&#xff0c;传统的监控系统正逐步向智能化方向转变。海思Hi3520D作为一款高性能的网络视频处理芯片&#xff0c;在NVR&#xff08;网络视频录像机&#xff09;领域有着广泛的应用。本方案旨在探讨如何利用海思Hi3520D芯片的强大功能对现有的NVR系统进行…

软件测试需求分析有多重要?软件测评公司如何进行测试需求分析?

软件测试需求分析是指在软件测试过程中&#xff0c;对用户需求和功能需求进行深入理解和评估的过程。它主要帮助测试团队明确测试目标、制定测试策略&#xff0c;并根据需求制定测试用例。这一过程不仅提高了测试的效率&#xff0c;也降低了后续开发与测试中可能出现的问题。 …

Qt 0819作业

一、思维导图 二、字体对话框的实现 #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }void Widget::on_pushButton_clicked(…

ant design pro 技巧之自制复制到剪贴板组件

ant design pro 如何去保存颜色ant design pro v6 如何做好角色管理ant design 的 tree 如何作为角色中的权限选择之一ant design 的 tree 如何作为角色中的权限选择之二ant design pro access.ts 是如何控制多角色的权限的ant design pro 中用户的表单如何控制多个角色ant des…

【PyCharm安装】安装Python和PyCharm的注意事项!!!PyCharm常用的插件介绍。

安装Python的注意事项 确定所需版本&#xff1a;根据您的项目和库的要求&#xff0c;选择合适的Python版本进行安装。不同版本的Python可能支持不同的库和特性。确保网络连接&#xff1a;如果您使用的是在线安装方式&#xff0c;确保您的计算机有可靠的网络连接&#xff0c;以…

《Techporters架构搭建》-Day07 集成API文档工具

API文档化 前言API文档化历史集成Knife4j常用注解基本信息注解分组注解请求方法注解路径注解 使用示例 源码地址&#xff1a;请看day07 前言 在现代软件开发中&#xff0c;良好的API文档是团队协作和项目管理中不可或缺的一部分。OpenAPI规范&#xff08;前身为Swagger&#x…

AI绘画Stable Diffusion插件—LayerDiffusion 分层控图新突破!生成透明图片前后景图片融合,毫无违和感!

大家好&#xff0c;我是画画的小强 用AI绘画Stable Diffusion 生成透明图片怎么搞&#xff1f; 这要搁之前&#xff0c;我们需要生成完图片&#xff0c;然后放到去背景插件中调整参数去除背景&#xff01;效果一般般 如果想要在一张图片上添加主体&#xff0c;该怎么搞&#…

使用gpreftools测试性能

参考文献&#xff1a; C 性能分析工具调研_性能分析工具 gperf perf vergi 比较-CSDN博客性能测试工具CPU profiler(gperftools)的使用心得-CSDN博客gperftools使用方法和常见问题_pprof no nodes to print-CSDN博客c 分析 gperftools 总结 | Weakyon Blog 文章目录 安装使用 …

如何搭建知识库?2024年6款工具优质推荐

一、引言 在当今信息化时代&#xff0c;知识管理已成为企业提升竞争力和实现持续发展的关键。搭建一个高效、易用的知识库&#xff0c;不仅能帮助企业更好地整合和分享内部资源&#xff0c;还能提升员工的工作效率和创新能力。本文将详细介绍如何搭建知识库&#xff0c;并推荐…