Редактирование QAbstractTableModel без очистки предыдущих данных в ячейке - PullRequest
1 голос
/ 25 апреля 2019

Я создал модель на основе QAbstractTableModel, которая позволяет пользователю редактировать данные в этой модели. Модель отображается в QTableView в QMainWindow. Пока что в моей модели я могу сделать ячейки редактируемыми и сохранять все, что пользователь вводит после завершения редактирования.

Проблема в том, что когда пользователь начинает редактирование, он «очищает» предыдущее содержимое этой ячейки. Так, если, например, я хотел изменить только написание строки в ячейке, я должен заново ввести все значение. При редактировании мне бы хотелось, чтобы редактор начинал с данных, которые уже есть в модели, а не с пустыми.

Как я могу это сделать?

Пример выпуска:

Прежде чем я начну редактировать ячейку:

* +1012 *Before editing

Как только я начинаю редактирование, ячейка пуста. Я хотел бы, чтобы он помечался предыдущим значением в модели:

Once editing begins

Вот минимальный пример моей модели. Моя фактическая модель намного больше и использует структуру вместо двумерного массива QVariants для хранения данных.

Заголовок:

const int COLS= 2;
const int ROWS= 6;

class EditableTableModel : public QAbstractTableModel
{
    Q_OBJECT

private:
    QVariant tableData[ROWS][COLS];

public:
    EditableTableModel(QObject *parent = nullptr);
    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;
    bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
    QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
    Qt::ItemFlags flags(const QModelIndex &index) const override;

signals:
    void editCompleted(QString);

};

Реализация:

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

int EditableTableModel::rowCount(const QModelIndex & /*parent*/) const
{
   return ROWS;
}


int EditableTableModel::columnCount(const QModelIndex & /*parent*/) const
{
    return COLS;
}


QVariant EditableTableModel::data(const QModelIndex &index, int role) const
{
    int row = index.row();
    int col = index.column();

    switch (role) {
    case Qt::DisplayRole:
        return tableData[row][col];
    }

    return QVariant();
}


bool EditableTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if (role == Qt::EditRole) {
        if (!checkIndex(index))
            return false;

        tableData[index.row()][index.column()] = value;
        return true;

    }
    return false;
}


QVariant EditableTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
        switch (section) {
        case 0:
            return QString("First Name");
        case 1:
            return QString("Last Name");
        }
    }
    return QVariant();
}


Qt::ItemFlags EditableTableModel::flags(const QModelIndex &index) const
{
    return Qt::ItemIsEditable | QAbstractTableModel::flags(index);
}

1 Ответ

3 голосов
/ 25 апреля 2019

Данные должны быть возвращены для Qt::EditRole в методе data(). Следующее должно работать:

QVariant EditableTableModel::data(const QModelIndex &index, int role) const
{
    int row = index.row();
    int col = index.column();

    switch (role) {
    case Qt::DisplayRole:
    case Qt::EditRole:                  //   <-- add this line          
        return tableData[row][col];
    }

    return QVariant();
}

Обратите внимание, что в приведенном выше корпусе коммутатора используется нечто, известное как fallthrough , так что корпус коммутатора будет совпадать как для Qt::DisplayRole, так и Qt::EditRole.

.
...