Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Unsolved Passing Model to a Dialog. View does not get updated properly

    General and Desktop
    2
    3
    56
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • S
      sandro4912 last edited by

      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?

      JonB 1 Reply Last reply Reply Quote 0
      • JonB
        JonB @sandro4912 last edited by JonB

        @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?

        1 Reply Last reply Reply Quote 2
        • S
          sandro4912 last edited by

          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.

          1 Reply Last reply Reply Quote 0
          • First post
            Last post