Search code examples
c++mysqlqtuser-interfaceqtableview

How to display a simple QMap in a QTableView in Qt?


I have a QMap called map. I initialize this map with couple of row of data from my database. Now I send this map to another class which contain GUI classes. In my GUI I have a TableView item. I need to show this map in any order in this TableView.

I have seen couple of examples, but all of them are for one vector which has only one field. And they used another class to form the view. I wondered if anyone has done this before and can help me with that.


Solution

  • Wrap the QMap in a subclass of QAbstractTableModel and set it to the view. Following, a basic functional example:

    File "mapmodel.h"

    #ifndef MAPMODEL_H
    #define MAPMODEL_H
    
    #include <QAbstractTableModel>
    #include <QMap>
    
    class MapModel : public QAbstractTableModel
    {
        Q_OBJECT
    public:
    
        enum MapRoles {
            KeyRole = Qt::UserRole + 1,
            ValueRole
        };
    
        explicit MapModel(QObject *parent = 0);
        int rowCount(const QModelIndex& parent = QModelIndex()) const;
        int columnCount(const QModelIndex& parent = QModelIndex()) const;
        QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
        inline void setMap(QMap<int, QString>* map) { _map = map; }
    
    private:
        QMap<int, QString>* _map;
    };
    
    #endif // MAPMODEL_H
    

    File "mapmodel.cpp"

    #include "mapmodel.h"
    
    MapModel::MapModel(QObject *parent) :
        QAbstractTableModel(parent)
    {
        _map = NULL;
    }
    
    int MapModel::rowCount(const QModelIndex& parent) const
    {
        if (_map)
            return _map->count();
        return 0;
    }
    
    int MapModel::columnCount(const QModelIndex & parent) const
    {
        return 2;
    }
    
    QVariant MapModel::data(const QModelIndex& index, int role) const
    {
        if (!_map)
            return QVariant();
        if (index.row() < 0 ||
            index.row() >= _map->count() ||
            role != Qt::DisplayRole) {
            return QVariant();
        }
        if (index.column() == 0)
            return _map->keys().at(index.row());
        if (index.column() == 1)
            return _map->values().at(index.row());
        return QVariant();
    }
    

    Example of use:

    // ...
    QMap<int, QString> map;
    map.insert(1, "value 1");
    map.insert(2, "value 2");
    map.insert(3, "value 3");
    
    MapModel mapmodel;
    mapmodel.setMap(&map);
    
    YourTableView.setModel(&mapmodel);
    // ...
    

    It will show a table view populated as follows:

    enter image description here