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. Best way to subclass setData() in subclass of QSqlTableModel
Forum Updated to NodeBB v4.3 + New Features

Best way to subclass setData() in subclass of QSqlTableModel

Scheduled Pinned Locked Moved Solved General and Desktop
7 Posts 2 Posters 634 Views 1 Watching
  • 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.
  • M Offline
    M Offline
    montanaviking
    wrote on last edited by
    #1

    Hi, I'm still an amateur in Qt and C++. I was wondering the best way to reimplement setData() in my class Paper_Model which is derived from QSqlTableModel as shown?
    #############
    // class definition
    #include <sqlsetup.h>
    #ifndef SQL_SQLTABLEMODEL_H
    #define SQL_SQLTABLEMODEL_H

    class Paper_Model: public QSqlTableModel {
    Q_OBJECT
    public:
    explicit Paper_Model(QObject* parent=Q_NULLPTR,const QString tablename="");
    QString getColumnName(int col);
    QSqlError query(const QString filter=QString("1"));
    QSqlRecord undo_redo(QString undoredo); //undo model edit
    bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) override;
    private:
    QVector<QSqlRecord> recordundoredo; // vector which holds copies stack of record under edit

    };

    #endif //SQL_SQLTABLEMODEL_H
    ##############################
    // class
    #include "sqlsetup.h"
    #include "Paper_Model.h"
    //#include "sqlForeignKeyDelegate.h"
    using namespace std;
    Paper_Model::Paper_Model(QObject *parent,QString tablename):QSqlTableModel(parent)
    {
    this->setTable(tablename);
    this->setEditStrategy(QSqlTableModel::OnManualSubmit);
    }

    QString Paper_Model::getColumnName(int col) // find column name from column number
    {
    return this->record().fieldName(col);
    }

    // query database model
    QSqlError Paper_Model::query(const QString filter)
    {
    this->setFilter(filter);
    this->select();
    auto sqlerror=this->lastError();
    if(sqlerror.type() == QSqlError::ConnectionError)

    {
        cout<<"database connection ERROR on Paper Model table name " << this->tableName().toStdString()<<endl;
    }
    else if (sqlerror.type() == QSqlError::StatementError)
    {
        cout<<"sql statement ERROR on Paper Model table name " << this->tableName().toStdString()<<endl;
    }
    else if (sqlerror.type() == QSqlError::TransactionError)
    {
        cout<<"sql transaction ERROR on Paper Model table name " << this->tableName().toStdString()<<endl;
    }
    else if (sqlerror.type() == QSqlError::UnknownError)
    {
        cout<<"sql transaction ERROR on Paper Model table name " << this->tableName().toStdString()<<endl;
    }
    return sqlerror ;   // get errors if there are errors in the query
    

    }

    bool Paper_Model::setData(const QModelIndex &index, const QVariant &value, int role)
    {
    if(index.isValid() && (role==Qt::EditRole || role==Qt::DisplayRole))
    {
    // redo or undo update here

    }
    return QSqlTableModel::setData(index, value,role);
    

    }
    ###############################

    I would like to capture the data every time the user edits the query results as shown by the table which has model: Paper_Model
    This captured data would be used later to allow the user to undo or redo edits (code not written for this yet but would go in the //redo or update here
    line in the code above.

    My central question is this:
    For the most part, I want the Paper_Model::setData() to act like it would if not reimplemented with the exception of changing the redo/undo stack storage when the user edits the query results in the table. After capturing the user's edits, I would like to just send the data to the model as for the default setData behavior.
    Is it correct to include the line:
    return QSqlTableModel::setData(index, value,role);
    in method Paper_Model::setData
    to get the default behavior after doing the extra work?

    In general, when one wants default behavior in a subclassed method (call it Method()), is the following general code correct?
    SubClass::Method()
    {
    // do something

    return BaseClass::Method();
    }

    ########### OR to get default behavior if condition not met

    SubClass::Method()
    {
    if(condition)
    {
    // do something
    return ....
    }
    else
    {
    return BaseClass::Method();
    }

    where BaseClass is the base class of the class SubClass?

    Thanks so much,
    Phil

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      Shouldn't you implement the undo stack at the editor level rather than in such a backend class ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      1
      • M Offline
        M Offline
        montanaviking
        wrote on last edited by
        #3

        Thanks for your reply SGaist, I'll look into this. I believe you're talking about using a delegate to implement the undo stack?
        Even so, I'm still curious about the general question of getting default behavior (i.e. bypass case) for reimplemented methods?
        Thanks,
        Phil

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          I was rather thinking about a dedicated editor.

          To get the default behaviour call the base class method.

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          0
          • M Offline
            M Offline
            montanaviking
            wrote on last edited by
            #5

            Hi SGaist,
            I suspected this was the case, i.e. to call the base class to get default behavior, but wanted to check with you experts.
            I think I wanted to send the entire record (table row) to the undo/redo stack every time the user edits a cell in that row. I would likely change the row's background color (via reimplementing the data() method with row) to indicate it's been altered and allow the user to undo or redo their changes to that row. The shown table rows would be those from the last query results and the user would be allowed to alter any of the rows and independently undo or redo each row's alterations. After the user is satisfied with his/her changes, they could send them to the underlying database.
            If the undo/redo were applied only to a single cell at a time, I would definitely use a delegate. However, I was thinking that since the entire row would be subject to undo/redo, it would be better to just modify the undo/redo stack on each user edit which would be caught by the reimplemented setData() method. I would then call the base class:setData() to go ahead with default behavior after capturing the user's edits onto the redo/undo stack.
            Does this make any sense?
            Thanks!
            Phil

            1 Reply Last reply
            0
            • M Offline
              M Offline
              montanaviking
              wrote on last edited by
              #6

              OK, I re-read your answer. You didn't propose an editor within a delegate but rather a standalone dedicated editor. I'm not sure how this would work and I'm thinking that I would then have to generate a whole table/widget entry mechanism just for this editor? I might be missing something obvious here?
              Thanks again,
              Phil

              1 Reply Last reply
              0
              • SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on last edited by
                #7

                I was thinking about the books example but you should take a look at the cached table example.

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                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