1

I try to implement a table view with two columns. The right columns shows parameters, which should not be changed by runtime, and left column shows values, that should be updated constantly at runtime. For this I implement a data model (derived from QAbstractTableModel). After setting up this I got a table with 3 rows and 2 columns and the right columns shows the parameters. The left columns however remains empty. And after hours I didn't find a solution for this. This is the relevant code of my data model I think:

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

    if (index.row() >= m_parameter.size()) {
        return QVariant();
    }

    if (role == Qt::DisplayRole || role == Qt::EditRole) {
        switch (index.column()) {
        case 0:
            return m_parameter.at(index.row());
            break;
        case 1:
            return m_value.at(index.row());
            break;
        }
    }
    return QVariant();
}


bool DataTableModel::setData(const QModelIndex& index, const QVariant& value, int role)
{
    if (!index.isValid() && role != Qt::EditRole) {
        return false;
    }
    //change only values in column 1
    if (index.column() == 1) {
        m_value.replace(index.row(), value.toString());
        emit dataChanged(index, index, { role });
        return true;
    }
    return true;
}


bool DataTableModel::insertRows(int row, int count, const QModelIndex& parent)
{
    //the following two methods emits signals that tells the view that the data should be changed
    beginInsertRows(QModelIndex(), row, row + count - 1);
    for (int i = 0; i < count; ++i) {
        m_parameter.insert(row, "");
        m_value.insert(row, "");
    }
    endInsertRows();
    return true;
}

In the main class I have a function that calles the functions of the model:

void QVideoMeter::QAddTableContent()
{
    QVariant value(QValueList());

    m_tableDataModel->insertRows(0, 3, QModelIndex()); //insert 3 rows
    m_tableDataModel->AddData(QParameterList());
    m_tableDataModel->setData(QModelIndex(), value, 2);
}

QList<QString> QVideoMeter::QValueList() 
{
    QList<QString> values;
    values.append("Test");
    values.append("Hallo");
    values.append("Welt");
    return values;
}

Please, can someone of you review my code and tell me what I'm doing wrong?

taathy
  • 155
  • 1
  • 1
  • 9
  • You don't call m_tableDataModel->setData() with the correct values. You have to pass the correct QModelIndex instead an invalid one and also a valid row and not '2'. – chehrlic Jan 16 '22 at 12:34
  • According to the docs setData is defined with `setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole)`. So '2' defines Qt::EditRole. I think there is a problem with the index too, but most importend for me is the question: Did I have to call the virtual setData() really or must I implement setData() twice? Can't find a best practice for this. – taathy Jan 16 '22 at 14:41
  • I already said that you have to pass a proper model index. And use enums instead values - noone knows out of the box that '2' is Qt::EditRole. – chehrlic Jan 16 '22 at 16:52

1 Answers1

0

Refer to the below two links. They provide the necessary concepts and examples:

  1. QAbstractItemModel Subclass
  2. Editable Tree Model Example

An editable model needs to provide implementations of setData() and setHeaderData(), and must return a suitable combination of flags from its flags() function.

Since this example allows the dimensions of the model to be changed, we must also implement insertRows(), insertColumns(), removeRows(), and removeColumns().

void MainWindow::insertRow()
{
    const QModelIndex index = view->selectionModel()->currentIndex();
    QAbstractItemModel *model = view->model();

    if (!model->insertRow(index.row()+1, index.parent()))
        return;

    updateActions();

    for (int column = 0; column < model->columnCount(index.parent()); ++column) {
        const QModelIndex child = model->index(index.row() + 1, column, index.parent());
        model->setData(child, QVariant(tr("[No data]")), Qt::EditRole);
    }
}
Arun Kumar B
  • 196
  • 9