Qt 自定义可编辑 模型视图

  转载自:https://blog.51cto.com/9291927/1890098

一、QAbstractItemModel为自定义模型提供了一个足够灵活的接口,能够支持数据源的层次结构,能够对数据进行增删改操作,还能够支持拖放。QT提供了 QAbstarctListModel和QAbstractTableModel两个类来简化非层次数据模型的开发,适合于结合列表和表格使用。

  自定义模型需要考虑模型管理的的数据结构适合的视图的显示方式。如果模型的数据仅仅用于列表或表格的显示,那么可以使用QAbstractListModel或者 QAbstractTableModel。但如果模型的数据具有层次结构,并且必须向用户显示出层次结构,只能选择QAbstractItemModel。不管底层数据结构是如何组织的,都要直接考虑适应于标准的 QAbstractItemModel的接口,可以让更多视图能够轻松访问到模型。

  CurrencyModel.h文件:

#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文件:

#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();
}
在MainWindow中ui中添加QTableView表格控件。
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;
}

  效果图如下:

  

猜你喜欢

转载自www.cnblogs.com/jiangson/p/10954421.html