When a row is going to be edited, an index is passed into the editing dialogue.
The edit works fine.
When I want to add a row, I don't pass an index to the dialogue constructor, so it knows that it's supposed to add a new row.
Here's the code of function reacting to dialogue's buttons
void DialogAddCl::on_buttonBox_clicked(QAbstractButton *button)
{
// prepare
m->database().transaction();
QString debugstr;
auto chi4 = ui->buttonBox->buttonRole(button);
int rowCount = m->rowCount();
switch (chi4) {
case QDialogButtonBox::AcceptRole:
if (!ind->isValid())
// insert
if (!m->insertRow(rowCount, *ind))
{
QMessageBox::critical (this, "Error inserting into model", m->lastError().text(), QMessageBox::Cancel);
break;
}
else
{
m->setData(m->index(rowCount, 0), rowCount+1);
}
else
{
// update
rowCount = ind->row();
}
m->setData(m->index(rowCount, 1), ui->name->text());
m->setData(m->index(rowCount, 2), ui->addr->text());
// 12 other setData() calls
if (m->submitAll())
{
m->database().commit();
}
else
{
// rollback if error
m->database().rollback();
debugstr = QString(m->database().lastError().text());
QMessageBox::critical (this, "Database returned an error",
m->database().lastError().text(), QMessageBox::Cancel);
}
case QDialogButtonBox::RejectRole:
this->close();
break;
case QDialogButtonBox::ResetRole:
fillFields();
break;
default:
break;
}
}
Here's a piece of dialogaddcl.h:
private:
Ui::DialogAddCl *ui;
QSqlTableModel* m;
QModelIndex* ind;
So, m->submitAll()
works fine if I edit an existing record, and fails if I try to submit freshly inserted row. I have checked with debugging, setData()
calls work fine even when adding, so it's not DB expecting NOT NULL
fields and giving an error.
By the way, maybe somebody can point out a method to catch the actual error text? I tried with debugstr
, but it always only contains empty string. So does the error message that I print
To insert a row to QSqlTableModel
you should not use setData()
directly, if you must not use insertRecord()
, where you indicate the row and the QSqlRecord
. The QSqlRecord
can be obtained through the record()
method of the model.
InsertDialog dial;
if(dial.exec()== InsertDialog::Accepted){
db.transaction();
QString f = dial.firstname();
QString l = dial.lastname();
QSqlRecord record = model.record();
/* since the id field has the autoincrement attribute,
* it is not necessary to indicate its value,
* that is because this field of the request is removed.
*/
record.remove(record.indexOf("id"))
record.setValue("firstname", f);
record.setValue("lastname", l);
/*-1 is set to indicate that it will be added to the last row*/
if(model.insertRecord(-1, record)){
qDebug()<<"successful insertion";
model->submitAll();
}
else{
db.rollback();
}
}
In the following link you will find an example.