Updating QStandardItemModel when records added to QSQLITE database



  • Hi,
    I have a QStandardItemModel displaying records from a db through tableView. How can I update the the records displayed in tableView when a record is added to the db?
    Thank you.



  • SQLite has no signaling capabilities (QSqlDriver::hasFeature(QSqlDriver::EventNotifications) == false) so you have 3 alternative routes:

    • if the database is updated just from your app just emit a signal every time you update it and have a slot refresh the model
    • if the database is updated just from your app but you can have multiple users/instances running at the same time use QTcpSocket to signal others when something changed
    • if the database can be changed externally the only choice is to run select from a periodic timer and check the returned table against yours

  • Moderators



  • @VRonin
    It is updated only from my app. Do I have to write my own signals and slots?



  • @gabor53

    • declare a signal in the class that does the update (I presume it's a QObject) and emit it after you perform the update
    • define a slot that takes care of refreshing the table
    • connect the two

  • Lifetime Qt Champion

    Hi,

    Out of curiosity, why not use QSqlTableModel since you are already using QTableView ?



  • @SGaist
    I should have



  • @VRonin
    is there a tutorial somewhere about custom signals and slots? I wasn't able to find anything recent. Thank you.



  • @gabor53 That's pretty much the core of Qt: http://doc.qt.io/qt-5/signalsandslots.html



  • I came up with the following:
    .h file:

    
    signals:
        void RecAdded();
    
    private slots:
        void updateTable();
    
    

    In cpp:

     connect(on_pushButton_Add_to_DB_clicked(),SIGNAL(recAdded()),this,SLOT(updateTable ()));
    

    The full cpp just in case: cpp

    When I try to build it, it gives me the following error message:

    C:\Programming\Projects\Folkfriends_1_0\review.cpp:125: error: invalid use of void expression
    connect(on_pushButton_Add_to_DB_clicked(),SIGNAL(recAdded()),this,SLOT(updateTable ()));
    ^
    What causes this error? Thank you.


  • Moderators

    @gabor53 The reason is connect expects an object as its first parameter but your on_pushButton_Add_to_DB_clicked() returns a void and thus the error invalid use of void expression
    Return an object from that function or use an object directly(makes it more easier to understand).



  • @p3c0
    I understand now how it works. In this case the user clicks a button and the record is added to the database. What kind of object do you recommend to create to update the model?



  • You don't have to create any more objects, just replace on_pushButton_Add_to_DB_clicked() with the actual button something like ui->Add_to_DB



  • @VRonin
    Thank you. Now I have

    connect(ui->pushButton_Add_to_DB,SIGNAL(recAdded()),this,SLOT(updateTable ()));
    

    which works. My new error message is

    QObject::connect: No such signal QPushButton::recAdded() in ..\Folkfriends_1_0\review.cpp:125
    QObject::connect:  (sender name:   'pushButton_Add_to_DB')
    QObject::connect:  (receiver name: 'Review')
    

    In .h I have the following:

    signals:
        void RecAdded();
    

    Is this correct?
    Thank you.



  • sorry my bad, it should be:

    connect(this,SIGNAL(recAdded()),this,SLOT(updateTable ()));

    then call emit recAdded() after you added the record in your database



  • @VRonin
    I modified like this:

     querys.prepare("INSERT INTO Items (ID, Name, Pic, Description, Month, Day, Year, History, Age, Notes, Color, Material, Signed, What) VALUES(:ID, :Name, :Pic, :Description, :Month, :Day, :Year, :History, :Age, :Notes, :Color, :Material, :Signed, :What)" );
        querys.bindValue (":ID",sIDReview);
        querys.bindValue (":Name",nameReview);
        querys.bindValue (":Pic",fileByteArray);
        querys.bindValue (":Description",descriptionReview);
        querys.bindValue (":Month",monthReview);
        querys.bindValue (":Day",dayReview);
        querys.bindValue (":Year",yearReview);
        querys.bindValue (":History",historyReview);
        querys.bindValue (":Age",ageReview);
        querys.bindValue (":Notes",notesReview);
        querys.bindValue (":Color",colorReview);
        querys.bindValue (":Material",materialReview);
        querys.bindValue (":Signed",SignedbyReview);
        querys.bindValue (":What",whatReview);
    
        bool result = querys.exec ();
    
        if(!result)
            {
                qDebug() <<"Error inserting into the main db!" << querys.lastError ();
    
                QMessageBox::warning (this,"Add to Database Warning","<b><font size='16' color='red'>Error 1002: The Friend was not added to the database.");
    
            }
        else
            {
                qDebug() << "Entered FunctAdd OK loop.";
    
    
                QMessageBox::information (this,"Confirmation","<b><font size = '16' color = 'green'>The Friend was added to the database.</font>");
    
                emit RecAdded ();
            }
    
       connect(this,SIGNAL(recAdded()),this,SLOT(updateTable ()));
    
    }
    
    void Review::on_pushButton_Fix_clicked()
    {
        Additem *mAdditem = new Additem(this);
        mAdditem->FixFriend (sIDReview, nameReview, whatReview, fileNameReview, materialReview, colorReview, descriptionReview, monthReview, dayReview, yearReview, SignedbyReview, historyReview, ageReview, notesReview);
    
        mAdditem->show ();
    }
    
    void Review::updateTable()
    {
        qDebug() << "UpdateTable triggered!";
    
        MainWindow *myMainWindow = new MainWindow(this);
        myMainWindow->Addview ();
        myMainWindow->show ();
    }
    
    

    It still says
    QObject::connect: No such signal Review::recAdded() in ..\Folkfriends_1_0\review.cpp:125
    QObject::connect: (sender name: 'Review')
    QObject::connect: (receiver name: 'Review')



  • 2 problems:

    • it's case sensitive
    • the connect "must" be done in the constructor

    so in the Review constructor put:

    connect(this,&Review::RecAdded,this,&Review::updateTable);
    

    I used the new connect sintax as it's safer



  • This works> Thank you very much.


  • Lifetime Qt Champion

    Still, why not change the model to use a more adequate ?



  • @SGaist
    I will. Actually I'm doing it now.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.