Passing Model to a Dialog. View does not get updated properly
-
Ok I have the following Issue:
I have a MainWindow were I use a Model derrived from
QSqlTableModel
.MainWindow::MainWindow() :mQuestionModel{ new QuestionSqlTableModel{ this } }, mPictureDelegate{ new PictureDelegate } { mQuestionModel->setTable("questions"); mQuestionModel->setSort(QuestionColumn::id, Qt::AscendingOrder); mQuestionModel->setHeaderData( QuestionColumn::askedQuestion, Qt::Horizontal, tr("Question")); mQuestionModel->setHeaderData( QuestionColumn::answer1, Qt::Horizontal, tr("Answer1")); mQuestionModel->setHeaderData( QuestionColumn::answer2, Qt::Horizontal, tr("Answer2")); mQuestionModel->setHeaderData( QuestionColumn::answer3, Qt::Horizontal, tr("Answer3")); mQuestionModel->setHeaderData( QuestionColumn::answer4, Qt::Horizontal, tr("Answer4")); mQuestionModel->setHeaderData( QuestionColumn::correct_answer, Qt::Horizontal, tr("Correct Answer")); mQuestionModel->setHeaderData( QuestionColumn::picture, Qt::Horizontal, tr("Picture")); mQuestionModel->select(); //....
When the user pushes a Action I create a
QTableView
were the user can see existing entries and edit them.So far so good this all seems to work.
Now i want to open a Dialog to have the user add more entries into database.
void MainWindow::addQuestions() { auto addNewQuestionDialog = new AddNewQuestionDialog{ mQuestionModel }; addNewQuestionDialog->setAttribute(Qt::WA_DeleteOnClose); addNewQuestionDialog->show(); addNewQuestionDialog->exec(); }
My Idea was to pass the Model to the Dialog and write directly into the database with
insertRecord
whenaccept
happens:void AddNewQuestionDialog::accept() { auto picturePath = ui->fileNamelineEdit->text(); QByteArray picture; if(!picturePath.isEmpty()) { QPixmap inPixmap; if (inPixmap.load(picturePath)) { QBuffer inBuffer(&picture); inBuffer.open( QIODevice::WriteOnly ); inPixmap.save(&inBuffer, "PNG"); } } mModel->database().transaction(); auto record = mModel->record(); record.field("id").setAutoValue(true); record.setValue(QuestionColumn::askedQuestion, ui->questionLineEdit->text()); record.setValue(QuestionColumn::answer1, ui->answer1LineEdit->text()); record.setValue(QuestionColumn::answer2, ui->answer2LineEdit->text()); record.setValue(QuestionColumn::answer3, ui->answer3LineEdit->text()); record.setValue(QuestionColumn::answer4, ui->answer4LineEdit->text()); record.setValue(QuestionColumn::correct_answer, correctAnswerAsInt()); record.setValue(QuestionColumn::picture, picture); if(!mModel->insertRecord(-1, record)) { qDebug() << "Failed to set record" << "The database reported an error: " << mModel->lastError().text() <<"RowCount" <<mModel->rowCount(); } if(mModel->submitAll()) { mModel->database().commit(); } else { mModel->database().rollback(); qDebug() << "Database Write Error" << "The database reported an error: " << mModel->lastError().text(); } QDialog::accept(); }
After the dialog closes the model gets updated but instead of showing a new number in the rows it shows a new empty entry with a
!
If i restart the app or look into the database the entry was correctly added.
Is the view out of sync?
Is it a bad practice to pass the model to the Dialog?
-
Ok I have the following Issue:
I have a MainWindow were I use a Model derrived from
QSqlTableModel
.MainWindow::MainWindow() :mQuestionModel{ new QuestionSqlTableModel{ this } }, mPictureDelegate{ new PictureDelegate } { mQuestionModel->setTable("questions"); mQuestionModel->setSort(QuestionColumn::id, Qt::AscendingOrder); mQuestionModel->setHeaderData( QuestionColumn::askedQuestion, Qt::Horizontal, tr("Question")); mQuestionModel->setHeaderData( QuestionColumn::answer1, Qt::Horizontal, tr("Answer1")); mQuestionModel->setHeaderData( QuestionColumn::answer2, Qt::Horizontal, tr("Answer2")); mQuestionModel->setHeaderData( QuestionColumn::answer3, Qt::Horizontal, tr("Answer3")); mQuestionModel->setHeaderData( QuestionColumn::answer4, Qt::Horizontal, tr("Answer4")); mQuestionModel->setHeaderData( QuestionColumn::correct_answer, Qt::Horizontal, tr("Correct Answer")); mQuestionModel->setHeaderData( QuestionColumn::picture, Qt::Horizontal, tr("Picture")); mQuestionModel->select(); //....
When the user pushes a Action I create a
QTableView
were the user can see existing entries and edit them.So far so good this all seems to work.
Now i want to open a Dialog to have the user add more entries into database.
void MainWindow::addQuestions() { auto addNewQuestionDialog = new AddNewQuestionDialog{ mQuestionModel }; addNewQuestionDialog->setAttribute(Qt::WA_DeleteOnClose); addNewQuestionDialog->show(); addNewQuestionDialog->exec(); }
My Idea was to pass the Model to the Dialog and write directly into the database with
insertRecord
whenaccept
happens:void AddNewQuestionDialog::accept() { auto picturePath = ui->fileNamelineEdit->text(); QByteArray picture; if(!picturePath.isEmpty()) { QPixmap inPixmap; if (inPixmap.load(picturePath)) { QBuffer inBuffer(&picture); inBuffer.open( QIODevice::WriteOnly ); inPixmap.save(&inBuffer, "PNG"); } } mModel->database().transaction(); auto record = mModel->record(); record.field("id").setAutoValue(true); record.setValue(QuestionColumn::askedQuestion, ui->questionLineEdit->text()); record.setValue(QuestionColumn::answer1, ui->answer1LineEdit->text()); record.setValue(QuestionColumn::answer2, ui->answer2LineEdit->text()); record.setValue(QuestionColumn::answer3, ui->answer3LineEdit->text()); record.setValue(QuestionColumn::answer4, ui->answer4LineEdit->text()); record.setValue(QuestionColumn::correct_answer, correctAnswerAsInt()); record.setValue(QuestionColumn::picture, picture); if(!mModel->insertRecord(-1, record)) { qDebug() << "Failed to set record" << "The database reported an error: " << mModel->lastError().text() <<"RowCount" <<mModel->rowCount(); } if(mModel->submitAll()) { mModel->database().commit(); } else { mModel->database().rollback(); qDebug() << "Database Write Error" << "The database reported an error: " << mModel->lastError().text(); } QDialog::accept(); }
After the dialog closes the model gets updated but instead of showing a new number in the rows it shows a new empty entry with a
!
If i restart the app or look into the database the entry was correctly added.
Is the view out of sync?
Is it a bad practice to pass the model to the Dialog?
@sandro4912
I'm not sure what's wrong in your code. It should be fine to pass the model (pointer) around as a parameter. For now, you don't show where you create the view ("I create aQTableView
" --- it hasn't gone out of scope, has it?) and how you attach it to the model, check its https://doc.qt.io/qt-5/qabstractitemview.html#rowsInserted slot is being called and what the row data looks like? Try an explicitmQuestionModel->select()
after thecommit()
, or back in main whenmQuestionModel->select()
returns? Immediately after thecommit()
, verify what the value inrecord.field("id")
is, it should be getting updated from the database? -
You are right adding
mModel->select();
after themModel->database().commit();
seems to update the View properly to the new data.However this is still weired. Why without it the View adds a row with a
!
? So it nows theres a new record but it does not know about the new data?record.field("id").setAutoValue(true);
was not necessary since id is auto generated so i removed it.