Mark
Mark

Reputation: 5070

Master detail with relational tables: how to properly submit new records?

I'm studying the masterdetail example but it does not fit my real case scenario. I cannot use the same approach of retrieving the relational model like this:

QSqlTableModel *artistModel = model->relationModel(2);

because my table has some relations, so I need a QSqlRelationalTableModel and I cannot cast a QSqlTableModel to a QSqlRelationalTableModel.

Here my master table:

.schema programs
CREATE TABLE programs         (id INT NOT NULL,          duration INT NOT NULL,          idSong INT NOT NULL,          name TEXT,          PRIMARY KEY (id),          FOREIGN KEY (idSong) REFERENCES songs(id));

and here the details table:

.schema timelines 
CREATE TABLE timelines         (idProgram INT NOT NULL,          time INT NOT NULL,          idBouquet TEXT,          idFanSpeed INT NOT NULL,          ton INT NOT NULL,          PRIMARY KEY (idProgram, time),          FOREIGN KEY (idProgram) REFERENCES programs(id),          FOREIGN KEY (idBouquet) REFERENCES bouquets(name),          FOREIGN KEY (idFanSpeed) REFERENCES fanSpeeds(id));

On my form I have two QTableView, for each one I set up the QSqlRelationalTableModel for both tables:

QSqlDatabase db = QSqlDatabase::database(DATABASE_NAME);
_modelPrograms = new QSqlRelationalTableModel(this, db);
_modelPrograms->setTable("programs");
_modelPrograms->setEditStrategy(QSqlRelationalTableModel::OnRowChange);
_modelPrograms->setRelation(static_cast<int>(ColumnsProgram::MODEL_COL_ID_SONG), QSqlRelation("songs", "id", "name"));
_modelPrograms->select();
ui->viewPrograms->setModel(_model);

_modelTimelines = new QSqlRelationalTableModel(this, db);
_modelTimelines->setTable("timelines");
_modelTimelines->setEditStrategy(QSqlRelationalTableModel::OnRowChange);
_modelTimelines->setRelation(static_cast<int>(ColumnsTimeline::MODEL_COL_ID_PROGRAM), QSqlRelation("programs", "id", "name"));
_modelTimelines.setRelation(static_cast<int>(ColumnsTimeline::MODEL_COL_ID_HUE_MODE), QSqlRelation("hueModes", "id", "name"));
_modelTimelines.setRelation(static_cast<int>(ColumnsTimeline::MODEL_COL_ID_FAN_SPEED), QSqlRelation("fanSpeeds", "name", "name"));
_modelTimelines->select();
ui->viewTimelines->setModel(_model);

then I keep in sync the details table with the selected master row:

connect(ui->tablePrograms->selectionModel(), &QItemSelectionModel::currentRowChanged, this, [=](const QModelIndex &current, const QModelIndex &previous)
        {
            const QAbstractItemModel *model = current.model();
            QModelIndex indexProgram = model->index(current.row(), static_cast<int>(ColumnsProgram::MODEL_COL_ID));
            int idProgram = model->data(indexProgram).toInt();
            _modelTimelines->setFilter(QString("idProgram=%1").arg(idProgram));
        });

it works: when I select a row in the master table I can see the filtered rows in the details table. With a QPushButton I add a new line to the model:

_modelTimelines->insertRow(_modelTimelines->rowCount());
QModelIndex index = _modelTimelines->index(_modelTimelines->rowCount() - 1, 0);
ui->viewTimelines->setCurrentIndex(index);
ui->viewTimelines->edit(index);

but when I fill the record and I press enter (or I change the row) it should submit to the database. It actually happens, but the QTableView shows an empty row with an exclamation mark:

submit

now the QTableView does not respond anymore. But if I change the row of the master table and select again the previous one the row is now visible.

What should I add to my code to allow a correct behavior of my table?

Upvotes: 1

Views: 25

Answers (0)

Related Questions