Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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 when accept 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 !

    0_1567842864299_d2f87848-eca7-4ef0-b646-d4e0ac25a52f-image.png

    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 a QTableView" --- 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 explicit mQuestionModel->select() after the commit(), or back in main when mQuestionModel->select() returns? Immediately after the commit(), verify what the value in record.field("id") is, it should be getting updated from the database?



  • You are right adding mModel->select(); after the mModel->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.


Log in to reply