zoukankan      html  css  js  c++  java
  • (四)Qt实现自定义模型基于QAbstractTableModel (一般)

    Qt实现自定义模型基于QAbstractTableModel

    两个例子

    例子1代码

    Main.cpp

    #include <QtGui>
    
    #include "currencymodel.h"
    
    int main(int argc, char *argv[])
    {
        QApplication app(argc, argv);
    
        //数据源
        QMap<QString, double> currencyMap;
        currencyMap.insert("AUD", 1.3259);
        currencyMap.insert("CHF", 1.2970);
        currencyMap.insert("CZK", 24.510);
        currencyMap.insert("DKK", 6.2168);
        currencyMap.insert("EUR", 0.8333);
        currencyMap.insert("GBP", 0.5661);
        currencyMap.insert("HKD", 7.7562);
        currencyMap.insert("JPY", 112.92);
        currencyMap.insert("NOK", 6.5200);
        currencyMap.insert("NZD", 1.4697);
        currencyMap.insert("SEK", 7.8180);
        currencyMap.insert("SGD", 1.6901);
        currencyMap.insert("USD", 1.0000);
    
        //自定义表模型
        CurrencyModel currencyModel;
        currencyModel.setCurrencyMap(currencyMap);
        //表视图
        QTableView tableView;
        //设置视图模型
        tableView.setModel(&currencyModel);
        //设置交替颜色
        tableView.setAlternatingRowColors(true);
    
        tableView.setWindowTitle(QObject::tr("Currencies"));
        tableView.show();
    
        return app.exec();
    }

    currencymodel.h

    #ifndef CURRENCYMODEL_H
    #define CURRENCYMODEL_H
    
    #include <QAbstractTableModel>
    #include <QMap>
    
    class CurrencyModel : public QAbstractTableModel
    {
    public:
        CurrencyModel(QObject *parent = 0);
    
        void setCurrencyMap(const QMap<QString, double> &map);
        int rowCount(const QModelIndex &parent) const;
        int columnCount(const QModelIndex &parent) const;
        QVariant data(const QModelIndex &index, int role) const;
        QVariant headerData(int section, Qt::Orientation orientation,
                            int role) const;
    
    private:
        QString currencyAt(int offset) const;
    
        QMap<QString, double> currencyMap;
    };
    
    #endif

    currencymodel.cpp

    #include <QtCore>
    
    #include "currencymodel.h"
    
    CurrencyModel::CurrencyModel(QObject *parent)
        : QAbstractTableModel(parent)
    {
    }
    
    void CurrencyModel::setCurrencyMap(const QMap<QString, double> &map)
    {
        currencyMap = map;
        //重置模型至原始状态,告诉所有视图,他们数据都无效,强制刷新数据
        reset();
    }
    
    //返回行数
    int CurrencyModel::rowCount(const QModelIndex & /* parent */) const
    {
        return currencyMap.count();
    }
    //返回列数
    int CurrencyModel::columnCount(const QModelIndex & /* parent */) const
    {
        return currencyMap.count();
    }
    
    //返回一个项的任意角色的值,这个项被指定为QModelIndex
    QVariant CurrencyModel::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) {
            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();
    }
    //返回表头名称,(行号或列号,水平或垂直,角色)
    QVariant CurrencyModel::headerData(int section,
                                       Qt::Orientation /* orientation */,
                                       int role) const
    {
        if (role != Qt::DisplayRole)
            return QVariant();
        return currencyAt(section);
    }
    //获取当前关键字
    QString CurrencyModel::currencyAt(int offset) const
    {
        return (currencyMap.begin() + offset).key();
    }

    例子2代码

    Main.cpp

    #include <QApplication>
    #include <QHeaderView>
    #include <QTableView>
    
    #include "citymodel.h"
    
    int main(int argc, char *argv[])
    {
        QApplication app(argc, argv);
    
        //保存城市名
        QStringList cities;
        cities << "Arvika" << "Boden" << "Eskilstuna" << "Falun"
               << "Filipstad" << "Halmstad" << "Helsingborg" << "Karlstad"
               << "Kiruna" << "Kramfors" << "Motala" << "Sandviken"
               << "Skara" << "Stockholm" << "Sundsvall" << "Trelleborg";
        //模型
        CityModel cityModel;
        //
        cityModel.setCities(cities);
    
        QTableView tableView;
        tableView.setModel(&cityModel);
        tableView.setAlternatingRowColors(true);
        tableView.setWindowTitle(QObject::tr("Cities"));
        tableView.show();
    
        return app.exec();
    }

    citymodel.h

    #ifndef CITYMODEL_H
    #define CITYMODEL_H
    
    #include <QAbstractTableModel>
    #include <QStringList>
    #include <QVector>
    
    class CityModel : public QAbstractTableModel
    {
        Q_OBJECT
    
    public:
        CityModel(QObject *parent = 0);
    
        void setCities(const QStringList &cityNames);
        int rowCount(const QModelIndex &parent) const;
        int columnCount(const QModelIndex &parent) const;
        QVariant data(const QModelIndex &index, int role) const;
        bool setData(const QModelIndex &index, const QVariant &value,
                     int role);
        QVariant headerData(int section, Qt::Orientation orientation,
                            int role) const;
        Qt::ItemFlags flags(const QModelIndex &index) const;
    
    private:
        int offsetOf(int row, int column) const;
    
        QStringList cities;
        QVector<int> distances;
    };
    
    #endif

    citymodel.cpp

    #include <QtCore>
    
    #include "citymodel.h"
    
    CityModel::CityModel(QObject *parent)
        : QAbstractTableModel(parent)
    {
    }
    //设定一下数据源
    void CityModel::setCities(const QStringList &cityNames)
    {
        cities = cityNames;
        //重新设置一下QVector distances的矩阵大小的,中间对角线为0不用存
        distances.resize(cities.count() * (cities.count() - 1) / 2);
        //填充所有距离值为0
        distances.fill(0);
        //刷新所有视图数据
        reset();
    }
    //模型行数
    int CityModel::rowCount(const QModelIndex & /* parent */) const
    {
        return cities.count();
    }
    //模型列数
    int CityModel::columnCount(const QModelIndex & /* parent */) const
    {
        return cities.count();
    }
    //赋值模型每个项的数据
    QVariant CityModel::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) {
            if (index.row() == index.column())
                return 0;
            int offset = offsetOf(index.row(), index.column());
            return distances[offset];
        }
        return QVariant();
    }
    //编辑一个项
    bool CityModel::setData(const QModelIndex &index,
                            const QVariant &value, int role)
    {
        if (index.isValid() && index.row() != index.column()
                && role == Qt::EditRole) {
            int offset = offsetOf(index.row(), index.column());
            distances[offset] = value.toInt();
            //交换对应项的模型索引
            QModelIndex transposedIndex = createIndex(index.column(),
                                                      index.row());
            //某项发生改变,发射信号( between topLeft and bottomRight inclusive)
            emit dataChanged(index, index);
            emit dataChanged(transposedIndex, transposedIndex);
            return true;
        }
        return false;
    }
    
    //返回列表头
    QVariant CityModel::headerData(int section,
                                   Qt::Orientation /* orientation */,
                                   int role) const
    {
        //返回在Cities字符串列表中给定偏移量的城市名称
        if (role == Qt::DisplayRole)
            return cities[section];
        return QVariant();
    }
    //返回对一个项相关的操作的标识符(例如,是否可以编辑或者是否已选中等)
    Qt::ItemFlags CityModel::flags(const QModelIndex &index) const
    {
        Qt::ItemFlags flags = QAbstractItemModel::flags(index);
        if (index.row() != index.column())
            flags |= Qt::ItemIsEditable;
        return flags;
    }
    //计算偏移量
    int CityModel::offsetOf(int row, int column) const
    {
        if (row < column)
            qSwap(row, column);
        return (row * (row - 1) / 2) + column;
    }

    转自:http://qimo601.iteye.com/blog/1534331

  • 相关阅读:
    一文搞定 Spring Boot & Shiro 实战
    CPU 到底是怎么认识代码的?涨姿势了!
    Java 可重入锁内存可见性分析
    大牛总结的 Git 使用技巧,写得太好了!
    厉害了,如何搭建一套自己的私有网盘?
    深入浅出 Java 中 JVM 内存管理
    SLA服务可用性4个9是什么意思?怎么达到?
    解决springboot配置@ControllerAdvice不能捕获NoHandlerFoundException问题
    mybatis多参数使用方法且其中有的参数是多个值使用in查询
    Optional导致的 java.util.NoSuchElementException: No value present
  • 原文地址:https://www.cnblogs.com/liushui-sky/p/5775579.html
Copyright © 2011-2022 走看看