PDA

View Full Version : Programatically add USerRole data to specific cell of QAbstractTableMode



franco.amato
26th November 2021, 04:47
Hi Qt lovers,
I am still in the learning phase of Model/View...

I have a class derived from QAbstractTableModel where I would add a QString to a specific cell at a specific time.

Internally the data of the model is stored in a QVector called m_reports but additionally I need to store some data that I need to retrieve from the MainWindow in a doubleclick event.

I though that setData is the correct function for that but I can't get it to work and I don't understand why.

Below the function that feed the model data


void SelectedListModel::appendReport(const QMultiMap<QString, QString> &report)
{
int row = m_reports.count();
beginInsertRows(QModelIndex(), row, row);
QString xmlFile = report.value("xmlFilePath");
qDebug() << xmlFile; // xmlFile contains right value
setData(index(row, 0), QVariant(xmlFile), Qt::UserRole + 1); // <-- this does not work, no data is written
m_reports.append(report);
endInsertRows();
}

In my MainWindow class, I catch the double-clicked event over the table view and I would get the value written with setData

?
connect(ui->selectedItemsView, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(showConfigureDialog(const QModelIndex &)));

And the relative slot from where I would get the value I need to process


void MainWindow::showConfigureDialog(const QModelIndex &index)
{
if (index.column() == 1)
{
return;
}

const QAbstractItemModel *model = index.model();
QString xmlFilePath = model->data(model->index(index.row(), 0), Qt::UserRole+1).toString();
qDebug() << "Cell Value: " << xmlFilePath; // This gives an empty output
}

I can not understand what can be the problem.
I hope to get some help.

Franco

d_stranz
26th November 2021, 05:21
What do you get if you call QModelIndex::data() directly instead of going through the model?

Does your setData() method actually save the string someplace for retrieval later?

Not really sure why you are calling your model to create a new QModelIndex when the one passed in has everything you want, especially after you have eliminated indexes with the wrong column.

franco.amato
26th November 2021, 11:06
What do you get if you call QModelIndex::data() directly instead of going through the model?

Does your setData() method actually save the string someplace for retrieval later?

Hi,
It's not my method, it's the QAbstractTableModel::setData(...)


Not really sure why you are calling your model to create a new QModelIndex when the one passed in has everything you want, especially after you have eliminated indexes with the wrong column.

I don't know :(
obviously I made a mistake. It's possible to have few lines of code to clarify my doubts please?

Added after 5 minutes:


What do you get if you call QModelIndex::data() directly instead of going through the model?

Adding:

qDebug() << index.data();

I got QVariant(Invalid)

d_stranz
26th November 2021, 16:48
QAbstractTableModel does not re-implement setData(), so it is using the implementation from its base class, QAbstractItemModel. The documentation for QAbstractItemModel::setData() says:


The base class implementation returns false. This function and data() must be reimplemented for editable models.

So if you have not implemented setData() in your own model (derived from QAbstractTableModel), then using the default setData() method is doing nothing to store your string.

This tutorial (https://doc.qt.io/qt-5/modelview.html) would be a good place to start. There is a section on creating an editable model.

franco.amato
26th November 2021, 22:21
QAbstractTableModel does not re-implement setData(), so it is using the implementation from its base class, QAbstractItemModel. The documentation for QAbstractItemModel::setData() says:



So if you have not implemented setData() in your own model (derived from QAbstractTableModel), then using the default setData() method is doing nothing to store your string.

This tutorial (https://doc.qt.io/qt-5/modelview.html) would be a good place to start. There is a section on creating an editable model.

Sorry I had misunderstood your previous message.
Yes I implemented a setData from my model.

I write it below:


bool SelectedListModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (!index.isValid())
{
return false;
}
if (role == Qt::EditRole)
{
m_reports[index.row()].replace("actionName", value.toString());

emit dataChanged(index, index);
return true;
}
}

It is not clear to me how to add data with a custom role.
Can you help me with a small example?

d_stranz
27th November 2021, 00:58
It is not clear to me how to add data with a custom role.

All you have to do is define a new role with the value > Qt:: UserRole, then call setData() with the string you want to add and the new role.

In the code you have posted above, the only time you save anything is when the role == EditRole. If you want setData() to save your string when the role == UserRole + 1, you must add an if () clause for that.

QTableView does not know anything about user roles so it will never ask for it, but you can call data() on your model (or the model index) with this role whenever you want to get the value for your custom role.