Jak zwizualizować/edytować std::map<int,int>?

0

Jak taki prosty widok danych zrobić w filozofii Qt ?

Przykład w Delphi wygląda tak:

image

0

Mam takie prymitywne rozwiązane na QTableWidget, jeżeli dopuszczasz jego użycie, to jest tutaj.

2

Coś w ten deseń:

template<typename Key, typename Value>
class StdMapItemModel : public QAbstractTableModel
{
public:
    StdMapItemModel(std::map<Key, Value>* map) m_map{map} {
    }

    int rowCount() const override {
        return map->size();
    }
    int columnCount() const override {
        return 2;
    }
    QVariant data(const QModelIndex &index, int role) const override {
        if (index.row() >= map->size() || role != Qt::DisplayRole) return {};
        auto it = std::next(map->begin(), index.row());
        if (index.column() == 0) {
            return it->first;
        } else {
            return it->second;
        }
    }

    QVariant QAbstractItemModel::headerData(int section, Qt::Orientation orientation, int role) const override {
        if (orientation == Qt::Horizontal) {
            return section == 0 ? tr("key") : tr("value");
        } else {
            return section;
        }
    }
    
private:
    std::map<Key, Value>* m_map;
};

Można też spokojnie dodać edycję, ale to już więcej dziergania.

3

Zresztą po co się wysilać:

Me:

How to subclass Qt QAbstractTableModel to expose `std::map` for edition in QTableView?

ChatGPT:

To subclass QAbstractTableModel and expose a std::map for editing in a QTableView, you can follow the following steps:

  1. Include the necessary headers:
#include <QAbstractTableModel>
#include <QMap>` 
  1. Define your model class, deriving from QAbstractTableModel. In this case, let's call it MapTableModel.
class MapTableModel : public QAbstractTableModel
{
    Q_OBJECT

public:
    explicit MapTableModel(QObject *parent = nullptr);
    ~MapTableModel();

    // Implement the necessary virtual functions for a table model
    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;
    QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
    bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
    Qt::ItemFlags flags(const QModelIndex &index) const override;

    // Define a function to set the map data
    void setMapData(const QMap<QString, QVariant> &data);

private:
    QMap<QString, QVariant> m_data;
};
  1. Implement the necessary virtual functions for a table model.
int MapTableModel::rowCount(const QModelIndex &parent) const {
    Q_UNUSED(parent)
    return m_data.count();
}

int MapTableModel::columnCount(const QModelIndex &parent) const {
    Q_UNUSED(parent)
    return 2; // We want two columns: key and value
}

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

    if (role == Qt::DisplayRole || role == Qt::EditRole)
    {
        QString key;
        QVariant value;
        int row = index.row();
        int col = index.column();

        if (row < m_data.count())
        {
            QMap<QString, QVariant>::const_iterator it = m_data.constBegin();
            std::advance(it, row);
            key = it.key();
            value = it.value();
        }

        if (col == 0)
            return key;
        else if (col == 1)
            return value;
    }

    return QVariant();
}

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

    if (orientation == Qt::Horizontal)
    {
        if (section == 0)
            return tr("Key");
        else if (section == 1)
            return tr("Value");
    }

    return QVariant();
}

bool MapTableModel::setData(const QModelIndex &index, const QVariant &value, int role) {
    if (!index.isValid())
        return false;

    if (role == Qt::EditRole)
    {
        int row = index.row();
        int col = index.column();

        if (row < m_data.count() && col == 1)
        {
            QMap<QString, QVariant>::iterator it = m_data.begin();
            std::advance(it, row);
            it.value() = value;
            emit dataChanged(index, index);
            return true;
        }
    }

    return false;
}

Qt::ItemFlags MapTableModel::flags(const QModelIndex &index) const {
    if (!index.isValid())
        return Qt::ItemIsEnabled;

    int col = index.column();

    if (col == 1)
        return QAbstractTableModel::flags(index) | Qt::ItemIsEditable;

    return QAbstractTableModel::flags(index);
}

Biorąc pod uwagę ostatnie szaleńcze postępy w rozwoju AI, wygląda na to, że trzeba bedzie szukać nowej profesji ;).

1
Adamek Adam napisał(a):

Jak taki prosty widok danych zrobić w filozofii Qt ?

Zobacz model jaki sobie zrobiłem do nauki

MyModel3.7z

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.