Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Passing Model to a Dialog. View does not get updated properly

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

Scheduled Pinned Locked Moved Unsolved General and Desktop
3 Posts 2 Posters 182 Views
  • 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 Offline
    S Offline
    sandro4912
    wrote on last edited by
    #1

    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?

    JonBJ 1 Reply Last reply
    0
    • S sandro4912

      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?

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by JonB
      #2

      @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
      2
      • S Offline
        S Offline
        sandro4912
        wrote on last edited by
        #3

        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
        0

        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved