Mark
Mark

Reputation: 5102

How to refresh a foreign key list in QSqlRelationalTableModel

In a Qt 6.8.2 Desktop application with SQLite I have two related tables:

Table master

id name
1 aaa
2 bbb

Table details

id idMaster value
1 1 foo
2 1 bar

In my QMainWindow I have two QTableView and I init them in this way:

QSqlDatabase db = QSqlDatabase::database(DATABASE_NAME);

// setup Details model
modelDetails = new QSqlRelationalTableModel(this, db);
modelDetails->setTable(TABLE_DETAILS);
modelDetails->setRelation(static_cast<int>(ColumnsDetails::MODEL_COL_ID_MASTER), QSqlRelation("master", "id", "name"));
modelDetails->setEditStrategy(TableModel::OnRowChange);
modelDetails->select();
// setup Details QTableView
ui->viewDetails->setModel(modelDetails);
ui->viewDetails->setItemDelegate(new QSqlRelationalDelegate(ui->viewDetails));

// setup Master model
modelMaster = new QSqlRelationalTableModel(this, db);
modelMaster->setTable(TABLE_MASTER);
modelMaster->setEditStrategy(TableModel::OnRowChange);
modelMaster->select();
// setup Master QTableView
ui->viewMaster->setModel(modelMaster);
ui->viewMaster->setItemDelegate(new QSqlRelationalDelegate(ui->viewMaster));

// when the user selects a Master row, filter the Details table
connect(ui->tableMaster->selectionModel(), &QItemSelectionModel::currentRowChanged, this, [=](const QModelIndex &current, const QModelIndex &previous)
{
    const QAbstractItemModel *model = current.model();
    QModelIndex indexMaster = model->index(current.row(), static_cast<int>(ColumnsMaster::MODEL_COL_ID));
    int idMaster = model->data(indexMaster).toInt();
    tableDetails.setFilter(QString("idMaster=%1").arg(idMaster));
});

If I add a row in the Details one, the idMaster column will show a nice QComboBox with aaa and bbb - the currently available Master names.

So far so good. My problem is how to keep in sync these values when the user changes the content of the Master table by adding or removing a row.

Note: I'm not talking how to propagate changes between the table (like the ON DELETE and ON UPDATE actions of the database). I just want the QComboBox shows the available Master names.

Adding or removing a row in Master table changes nothing in the list of the idMaster column in Details table. I tried to:

with no effect. Right now I have to stop and run again the application in order to show changes.

Given the above code, I don't see what I'm missing, since there is nothing else other selecting the data, set the relation and the filter.

I also inspected the QSqlRelationalTableModel source code (link) and the Master/Detail example (link) but I wasn't able to find the "magic" there.

What should I add to my code to "refresh" the currently available Master names in the idMaster column of Details table?

Upvotes: 0

Views: 21

Answers (1)

Mark
Mark

Reputation: 5102

You have to select() again the relationModel() not the model itself:

modelDetails->relationModel(static_cast<int>(ColumnsDetails::MODEL_COL_ID_MASTER))->select();

after editing/changing the Master table. In this way the foreign key column will display the actual data.

Upvotes: 0

Related Questions