qt的model view 使用示范

首先在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);
    }
}
相关推荐
用户805533698032 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner2 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz7 天前
QML Hello World 入门示例
qt
xcyxiner10 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner10 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner11 天前
DicomViewer (添加模型类)3
qt
xcyxiner11 天前
DicomViewer (目录调整) 2
qt
xcyxiner12 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
桥田智能13 天前
桥田智能 QT-650S:面向白车身焊装的 800kg 重载快换解决方案
开发语言·qt·系统架构
森G13 天前
75、服务器源码解析---------云视频服务项目
linux·服务器·网络·c++·qt