QSqlRelationalDelegate does not work on first show
-
Qt 6.8.0, I'm trying to use for the first time the
QSqlRelationalDelegate
withQSqlRelationalTableModel
. Here a snippet of my code:QSqlDatabase db = QSqlDatabase::database("mydb"); QSqlRelationalTableModel model = new QSqlRelationalTableModel(this, db); model->setTable("mytable"); model->setEditStrategy(QSqlRelationalTableModel::OnRowChange); model->select(); model->setRelation(MODEL_COL_ID_HUE_MODE, QSqlRelation("hueModes", "id", "name")); //... other relations ui->tableView->setModel(model); ui->tableView->setItemDelegate(new QSqlRelationalDelegate(ui->tableView));
When I enter a cell that is a foreign key it correctly shows a
QComboBox
filled with thedisplayColumn
, great!
When I finish to edit that cell the table still shows thedisplayColumn
(i.e. "name") and also this works as expected.But if I close my application and restart it again, the table now shows the
indexColumn
"id" value! The correct one, indeed, but I'm expecting to see the "name" value instead.Is there anything I should do to force the rendering of the
displayColumn
instead of theindexColumn
?By the way, my code is slightly different than the example:
-
I had to move the
model->select()
call before setting the relations, otherwise the behavior was odd. It shows only the headers with their names completely messed up -
and I had to remove the
std::unique_ptr<QTableView>
stuff, otherwise theQTableView
was empty
-
-
Qt 6.8.0, I'm trying to use for the first time the
QSqlRelationalDelegate
withQSqlRelationalTableModel
. Here a snippet of my code:QSqlDatabase db = QSqlDatabase::database("mydb"); QSqlRelationalTableModel model = new QSqlRelationalTableModel(this, db); model->setTable("mytable"); model->setEditStrategy(QSqlRelationalTableModel::OnRowChange); model->select(); model->setRelation(MODEL_COL_ID_HUE_MODE, QSqlRelation("hueModes", "id", "name")); //... other relations ui->tableView->setModel(model); ui->tableView->setItemDelegate(new QSqlRelationalDelegate(ui->tableView));
When I enter a cell that is a foreign key it correctly shows a
QComboBox
filled with thedisplayColumn
, great!
When I finish to edit that cell the table still shows thedisplayColumn
(i.e. "name") and also this works as expected.But if I close my application and restart it again, the table now shows the
indexColumn
"id" value! The correct one, indeed, but I'm expecting to see the "name" value instead.Is there anything I should do to force the rendering of the
displayColumn
instead of theindexColumn
?By the way, my code is slightly different than the example:
-
I had to move the
model->select()
call before setting the relations, otherwise the behavior was odd. It shows only the headers with their names completely messed up -
and I had to remove the
std::unique_ptr<QTableView>
stuff, otherwise theQTableView
was empty
@Mark81 said in QSqlRelationalDelegate does not work on first show:
I had to move the model->select() call before setting the relations, otherwise the behavior was odd. It shows only the headers with their names completely messed up
I would expect you to do
select
s after you have set up anyQSqlRelation
s. So that it knows to fetch the foreign stuff! To me it's worrying you do not work that way, as per the sample code.Start by verifying your database really does have the foreign keys per your
QSqlRelation
s.Also the fact that it behaves differently on re-run when you have not changed anything.
-
-
@Mark81 said in QSqlRelationalDelegate does not work on first show:
I had to move the model->select() call before setting the relations, otherwise the behavior was odd. It shows only the headers with their names completely messed up
I would expect you to do
select
s after you have set up anyQSqlRelation
s. So that it knows to fetch the foreign stuff! To me it's worrying you do not work that way, as per the sample code.Start by verifying your database really does have the foreign keys per your
QSqlRelation
s.Also the fact that it behaves differently on re-run when you have not changed anything.
@JonB perhaphs my SQL is wrong. Here is how I create the table and the keys:
bool MainWindow::createTableAlarms() { QSqlDatabase db = QSqlDatabase::database("mydb"); QSqlQuery query("DROP TABLE IF EXISTS alarms", db); query.exec(); QString sql = "CREATE TABLE alarms \ (id INT NOT NULL, \ idSong INT NOT NULL DEFAULT 0, \ h0 REAL NOT NULL DEFAULT 0.0, \ s0 REAL NOT NULL DEFAULT 0.0, \ l0 REAL NOT NULL DEFAULT 0.0, \ h1 REAL NOT NULL DEFAULT 0.0, \ s1 REAL NOT NULL DEFAULT 0.0, \ l1 REAL NOT NULL DEFAULT 0.0, \ idHueMode INT NOT NULL DEFAULT 0, \ idBouquet VARCHAR(32), \ idFanSpeed INT NOT NULL DEFAULT 0, \ ton INT NOT NULL DEFAULT 0, \ toff INT NOT NULL DEFAULT 0, \ fade_in INT NOT NULL DEFAULT 0, \ duration INT NOT NULL DEFAULT 1, \ idAlarmMode INT NOT NULL DEFAULT 0, \ gb VARCHAR(255), \ it VARCHAR(255), \ fr VARCHAR(255), \ PRIMARY KEY (id), \ FOREIGN KEY (idHueMode) REFERENCES hueModes(id), \ FOREIGN KEY (idFanSpeed) REFERENCES fanSpeeds(id), \ FOREIGN KEY (idAlarmMode) REFERENCES alarmModes(id));"; query.prepare(sql); return query.exec(); }
and here the SQL of the external tables, they are very similar:
bool MainWindow::createEnumTableHueModes() { QSqlDatabase db = QSqlDatabase::database("mydb"); QSqlQuery query("DROP TABLE IF EXISTS hueModes", db); query.exec(); QString sql = "CREATE TABLE hueModes \ (id INT NOT NULL, \ name VARCHAR(255), \ PRIMARY KEY (id));"; query.prepare(sql); query.exec(); query.exec("INSERT INTO hueModes(id, name) VALUES(0, 'Shortest distance');"); query.exec("INSERT INTO hueModes(id, name) VALUES(1, 'Longest distance');"); query.exec("INSERT INTO hueModes(id, name) VALUES(2, 'Left to right');"); query.exec("INSERT INTO hueModes(id, name) VALUES(3, 'Right to left');"); return true; }
If I do the following:
void FormAlarms::resetTable() { table.init("alarms", ui->table); table.setRelation(MODEL_COL_ID_HUE_MODE, QSqlRelation("hueModes", "id", "name")); table.setRelation(MODEL_COL_ID_ALARM_MODE, QSqlRelation("alarmModes", "id", "name")); table.setRelation(MODEL_COL_ID_FAN_SPEED, QSqlRelation("fanSpeeds", "id", "name")); table.setRelation(MODEL_COL_ID_SONG, QSqlRelation("songs", "id", "gb")); table.setRelation(MODEL_COL_ID_BOUQUET, QSqlRelation("bouquets", "name", "name")); table.init2(); }
where:
void TableEngine::init(QString name, QTableView *view) { this->view = view; QSqlDatabase db = QSqlDatabase::database("bloominence"); _model = new QSqlRelationalTableModel(this, db); _model->setTable(name); _model->setEditStrategy(QSqlRelationalTableModel::OnRowChange); } void TableEngine::init2() { _model->select(); view->setModel(_model); view->setItemDelegate(new QSqlRelationalDelegate(view)); }
this is what I see:
as you can see all the header's name are messed up.
Just to be clear:TableEngine
is my class where I set up the model (since it is used by several forms)- each form (like
FormAlarm
) just sets up the specific stuff for each table - these forms are displayed in the
QMainWindow
-
@JonB perhaphs my SQL is wrong. Here is how I create the table and the keys:
bool MainWindow::createTableAlarms() { QSqlDatabase db = QSqlDatabase::database("mydb"); QSqlQuery query("DROP TABLE IF EXISTS alarms", db); query.exec(); QString sql = "CREATE TABLE alarms \ (id INT NOT NULL, \ idSong INT NOT NULL DEFAULT 0, \ h0 REAL NOT NULL DEFAULT 0.0, \ s0 REAL NOT NULL DEFAULT 0.0, \ l0 REAL NOT NULL DEFAULT 0.0, \ h1 REAL NOT NULL DEFAULT 0.0, \ s1 REAL NOT NULL DEFAULT 0.0, \ l1 REAL NOT NULL DEFAULT 0.0, \ idHueMode INT NOT NULL DEFAULT 0, \ idBouquet VARCHAR(32), \ idFanSpeed INT NOT NULL DEFAULT 0, \ ton INT NOT NULL DEFAULT 0, \ toff INT NOT NULL DEFAULT 0, \ fade_in INT NOT NULL DEFAULT 0, \ duration INT NOT NULL DEFAULT 1, \ idAlarmMode INT NOT NULL DEFAULT 0, \ gb VARCHAR(255), \ it VARCHAR(255), \ fr VARCHAR(255), \ PRIMARY KEY (id), \ FOREIGN KEY (idHueMode) REFERENCES hueModes(id), \ FOREIGN KEY (idFanSpeed) REFERENCES fanSpeeds(id), \ FOREIGN KEY (idAlarmMode) REFERENCES alarmModes(id));"; query.prepare(sql); return query.exec(); }
and here the SQL of the external tables, they are very similar:
bool MainWindow::createEnumTableHueModes() { QSqlDatabase db = QSqlDatabase::database("mydb"); QSqlQuery query("DROP TABLE IF EXISTS hueModes", db); query.exec(); QString sql = "CREATE TABLE hueModes \ (id INT NOT NULL, \ name VARCHAR(255), \ PRIMARY KEY (id));"; query.prepare(sql); query.exec(); query.exec("INSERT INTO hueModes(id, name) VALUES(0, 'Shortest distance');"); query.exec("INSERT INTO hueModes(id, name) VALUES(1, 'Longest distance');"); query.exec("INSERT INTO hueModes(id, name) VALUES(2, 'Left to right');"); query.exec("INSERT INTO hueModes(id, name) VALUES(3, 'Right to left');"); return true; }
If I do the following:
void FormAlarms::resetTable() { table.init("alarms", ui->table); table.setRelation(MODEL_COL_ID_HUE_MODE, QSqlRelation("hueModes", "id", "name")); table.setRelation(MODEL_COL_ID_ALARM_MODE, QSqlRelation("alarmModes", "id", "name")); table.setRelation(MODEL_COL_ID_FAN_SPEED, QSqlRelation("fanSpeeds", "id", "name")); table.setRelation(MODEL_COL_ID_SONG, QSqlRelation("songs", "id", "gb")); table.setRelation(MODEL_COL_ID_BOUQUET, QSqlRelation("bouquets", "name", "name")); table.init2(); }
where:
void TableEngine::init(QString name, QTableView *view) { this->view = view; QSqlDatabase db = QSqlDatabase::database("bloominence"); _model = new QSqlRelationalTableModel(this, db); _model->setTable(name); _model->setEditStrategy(QSqlRelationalTableModel::OnRowChange); } void TableEngine::init2() { _model->select(); view->setModel(_model); view->setItemDelegate(new QSqlRelationalDelegate(view)); }
this is what I see:
as you can see all the header's name are messed up.
Just to be clear:TableEngine
is my class where I set up the model (since it is used by several forms)- each form (like
FormAlarm
) just sets up the specific stuff for each table - these forms are displayed in the
QMainWindow
-
@Mark81
If I were you I would cut your tables and code drastically: a couple of columns and one foreign key. When you have that working build back up.@JonB actually, it seems it works... the problem is in the column names. I said it "messed up" the names. But at a closer look, it appends the displayColumn and indexColumn. I didn't see this behavior in the pictures in the docs so I assumed I did something wrong.
Let me to test it a bit more to understand if it is working correctly.