Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Emit a signal only when an updated row is submitted to the database

In my Qt 6.8.2 Desktop application I need to use the OnRowChange edit strategy for a QSqlRelationalTableModel, since it is a design constraint for the UX. To keep the UI consistent and synced with all the tables it is mandatory to know when a row is actually updated in the database.

In my previous question I found a way to emit a signal when the submit() slot is invoked. Here my own subclassing of the QSqlRelationalTableModel:

#include <QSqlRelationalTableModel>

class TableModel : public QSqlRelationalTableModel
{
    Q_OBJECT

public:
    explicit TableModel(QObject *parent = nullptr, const QSqlDatabase &db = QSqlDatabase()) : QSqlRelationalTableModel(parent, db)
    {
    }

public slots:
    bool submit() override
    {
        bool ret = QSqlRelationalTableModel::submit();
        if (ret) emit rowSubmitted();
        return ret;
    }

signals:
    void rowSubmitted();
};

This code solved the issue I had in the linked question, but going ahead with the development I noticed the submit() function is called every time the user changes a row, no matter if he has actually changed something in the model!

I cannot live with this limitation. So I tried to change this line to:

if (ret && isDirty()) emit rowSubmitted();

but in this case the signal is never emitted, even just after editing a row. I guess because the model was already updated at this time.

My goal is to emit the signal only when a row is actually submitted to the database. I searched in the docs a way to retrieve the rows (count) just submitted to the database but I found nothing.

How can I improve my code in order to emit the rowSubmitted() signal only when a row is really submitted to the database?

like image 222
Mark Avatar asked Nov 22 '25 21:11

Mark


1 Answers

Here the correct implementation of the submit() function:

bool submit() override
{
    bool isDirtyShadow = isDirty();
    bool ret = QSqlRelationalTableModel::submit();
    if (ret && isDirtyShadow) emit rowSubmitted();
    return ret;
}

The trick is to save the isDirty() state before submitting to the database. Of course, after the changes are saved the model is not dirty anymore.

like image 197
Mark Avatar answered Nov 24 '25 11:11

Mark



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!