Qt custom editable model view

  Reprinted from: https: //blog.51cto.com/9291927/1890098

A, the QAbstractItemModel custom model provides an interface flexible enough to support hierarchical data source, the data can be CRUD operations, it is possible to support drag and drop. QT provides QAbstarctListModel and QAbstractTableModel two classes to simplify the development of non-hierarchical data model, suitable for use in conjunction with lists and tables.

  Custom model to consider how the data structure of the management model suitable view. If the data model is only used for a list or table display, you can use QAbstractListModel or QAbstractTableModel. However, if the data model has a hierarchical structure, and must be displayed to the user hierarchy, only select QAbstractItemModel. Regardless of the underlying data structures are organized, we must consider QAbstractItemModel direct interface adapted to the standard, allowing easy access to more view model.

  CurrencyModel.h file:

#ifndef CURRECYMODEL_H
#define CURRECYMODEL_H

#include <QAbstractTableModel>
#include <QAbstractItemModel>
#include <QMap>

class CurrecyModel : public QAbstractTableModel
{
    Q_OBJECT

public:
    explicit CurrecyModel(QObject *parent = 0);

    // 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;

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

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

    bool setData(const QModelIndex &index, const QVariant &value,int role = Qt::EditRole);

    void setCurrencyMap(const QMap<QString, double> &map);
private:
    QString currencyAt(int offset) const;
    QMap<QString, double> currencyMap;
};

#endif // CURRECYMODEL_H

  CurrencyModel.cpp file:

#include "CurrecyModel.h"

CurrecyModel::CurrecyModel(QObject *parent)
    : QAbstractTableModel(parent)
{
}

QVariant CurrecyModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if (role != Qt::DisplayRole)
    {
        return QVariant();
    }
    return currencyAt(section);
}

int CurrecyModel::rowCount(const QModelIndex &parent) const
{
    if (parent.isValid())
        return 0;

    return currencyMap.count();
}

int CurrecyModel::columnCount(const QModelIndex &parent) const
{
    if (parent.isValid())
        return 0;

    return currencyMap.count();
}

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

    if (role == Qt::TextAlignmentRole)
    {
       return int(Qt::AlignRight | Qt::AlignVCenter);
    }
    else if (role == Qt::DisplayRole || role == Qt::EditRole)
    {
       QString rowCurrency = currencyAt(index.row());
       QString columnCurrency = currencyAt(index.column());
       if (currencyMap.value(rowCurrency) == 0.0)
       {
           return "####";
       }
       double amount = currencyMap.value(columnCurrency)
               / currencyMap.value(rowCurrency);
       return QString("%1").arg(amount, 0, 'f', 4);
    }

    return QVariant();
}

bool CurrecyModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if (index.isValid() && index.row() != index.column() && role == Qt::EditRole)
    {
        QString columnCurrency = headerData(index.column(), Qt::Horizontal, Qt::DisplayRole).toString();
        QString rowCurrency = headerData(index.row(), Qt::Vertical, Qt::DisplayRole).toString();
        currencyMap.insert(columnCurrency, value.toDouble() * currencyMap.value(rowCurrency));
        emit dataChanged(index, index);
        return true;
    }
    return false;
}

Qt::ItemFlags CurrecyModel::flags(const QModelIndex &index) const
{
    Qt::ItemFlags flags = QAbstractItemModel::flags(index);
    if (index.row() != index.column())
    {
     flags |= Qt::ItemIsEditable;
    }
    return flags;
}

QString CurrecyModel::currencyAt(int offset) const
{
    return (currencyMap.begin() + offset).key();
}

void CurrecyModel::setCurrencyMap(const QMap<QString, double> &map)
{
    beginResetModel();
    currencyMap = map;
    endResetModel();
}
Add QTableView forms control in the MainWindow in ui.
MainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "CurrecyModel.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QMap<QString, double> data;
    data["USD"] = 1.0000;
    data["CNY"] = 0.1628;
    data["GBP"] = 1.5361;
    data["EUR"] = 1.2992;
    data["HKD"] = 0.1289;

    CurrecyModel *model = new CurrecyModel(this);
    ui->tableView->setModel(model);
    model->setCurrencyMap(data);
}

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

  The effect is as follows:

  

 

Guess you like

Origin www.cnblogs.com/jiangson/p/10954421.html