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. Add a new row at the end of QSqlTableModel while changing from last row
Forum Updated to NodeBB v4.3 + New Features

Add a new row at the end of QSqlTableModel while changing from last row

Scheduled Pinned Locked Moved General and Desktop
19 Posts 3 Posters 11.2k 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.
  • R Offline
    R Offline
    ras123
    wrote on last edited by
    #1

    Hi,
    QSqlTableModel is initialized with an empty row using "inserRows", and like to add one new row when user finished editing / entering data in this last row (A tab press, or return key pressed at the end of the last column in the last row, not by user clicked middle rows). Please let me know how to do it.
    Thanking You,
    Ras

    1 Reply Last reply
    0
    • A Offline
      A Offline
      andre
      wrote on last edited by
      #2

      What have you tried so far?

      Personally, I like the solution that an additional fake empty row is displayed at the bottom of the view, that allows you to add new data. You can use a proxy model over your QSqlTableModel to achieve that. That also makes it easier to make the proxy trigger adding a real new item in the underlying model (after wich the proxy will in turn again generate a new fake row).

      1 Reply Last reply
      0
      • R Offline
        R Offline
        ras123
        wrote on last edited by
        #3

        [quote author="Andre" date="1340694833"] You can use a proxy model over your QSqlTableModel to achieve that. [/quote]
        This is my first experience with QSql models, so please give some links for examples to do it.

        Currently, I insert new rows in QSqlTableModel on code start up, and saved the data by pressing a pushbutton. May be add a new row button can be used to insert new row, but I like to do automatically.

        Thanking You,
        Ras

        1 Reply Last reply
        0
        • A Offline
          A Offline
          andre
          wrote on last edited by
          #4

          I don't have an example ready to use for you.

          1 Reply Last reply
          0
          • R Offline
            R Offline
            ras123
            wrote on last edited by
            #5

            Hi,
            Can you explain how to do it by using proxy, a little more?
            Thanks
            Ras

            1 Reply Last reply
            0
            • A Offline
              A Offline
              andre
              wrote on last edited by
              #6

              Subclass [[doc:QIdentityProxyModel]], and reimplement these five functions:

              • rowCount. This one needs to return QIdentityProxyModel::rowCount() + 1;
              • data. This one return the base class result for all rows, except for the last row where you return whatever you want.
              • setData. If this one is called for the last row, insert the data as a new row in the underlying model, otherwise just forward the call to the base class.
              • flags. Return something sensible for the last row, base class for all other rows
              • index. Dito.

              Basically, the proxy is a very thin layer over the model you already have, only it tells the view that there is 1 more row and handles that row by itself.

              1 Reply Last reply
              1
              • R Offline
                R Offline
                ras123
                wrote on last edited by
                #7

                Hi,
                Thanks for the reply, but what is the difference in using original model for editing? like using an insertRow() function in QSqlRelationalTableModel. I almost succeeded this stage.

                I like to know how to add a new row or getting a signal when user moves from the last column last row by pressing a tab key. For example, inserted a blank row in the tableView on startup, and user inserting data in this row in each column. A tab press can change the column to the next, so from last column it needs to insert one new blank row, and the cursor must be in the first column on this newly created row. Is it possible?

                Thanks
                Ras

                1 Reply Last reply
                0
                • A Offline
                  A Offline
                  andre
                  wrote on last edited by
                  #8

                  There are some important differences:

                  The proxy solution is the more general one. It will also work with any other (editable) model.

                  Really inserting a row to display, in your case means that you are actually creating a database record. That might not be what you want.

                  In terms of UX design: the new row is there to see for the user, instead of the surprise of a new row being created on tab from the last cell of the previous row. That reduces the surpise factor, and thus enhances the experience. Furthermore, it allows for the mouse to be used to create the new row by simply clicking it.

                  However, if you feel that your approach is more suitable for your application: by all means, go ahead!

                  1 Reply Last reply
                  0
                  • R Offline
                    R Offline
                    ras123
                    wrote on last edited by
                    #9

                    [quote author="Andre" date="1340796957"]

                    In terms of UX design: the new row is there to see for the user, instead of the surprise of a new row being created on tab from the last cell of the previous row. That reduces the surpise factor, and thus enhances the experience. Furthermore, it allows for the mouse to be used to create the new row by simply clicking it.

                    [/quote]

                    How is your idea about the GUI for creating a new row? is it uses a push button?
                    Now I think the proxy approach is more suitable, and setData function can be used to validate data before submitting to the data base.

                    1 Reply Last reply
                    0
                    • A Offline
                      A Offline
                      andre
                      wrote on last edited by
                      #10

                      No, that's the beauty of it: no push buttons. Just an additional row that states something like:
                      [quote]
                      add new data
                      [/quote]

                      1 Reply Last reply
                      0
                      • R Offline
                        R Offline
                        ras123
                        wrote on last edited by
                        #11

                        Hi,
                        I cant write the function for rowCount, when executing/debugging it returns with following error
                        @Starting D:\QT\example\debug\example.exe...
                        ASSERT: "sourceIndex.isValid()" in file itemviews/qidentityproxymodel.cpp, line 169
                        D:\QT\example\debug\example.exe exited with code 3@

                        @int MyProxyModel::rowCount(const QModelIndex &parent) const
                        {
                        return 10;
                        }@

                        It is also not worked with
                        @int MyProxyModel::rowCount(const QModelIndex &parent) const
                        {
                        return QIdentityProxyModel::rowCount()+1;
                        }@

                        But no problems with the following, (without adding a row)
                        @
                        int MyProxyModel::rowCount(const QModelIndex &parent) const
                        {
                        return QIdentityProxyModel::rowCount();
                        }@

                        1 Reply Last reply
                        0
                        • A Offline
                          A Offline
                          andre
                          wrote on last edited by
                          #12

                          Did you also implement the rest of the functions I suggested you'd need to reimplement?

                          1 Reply Last reply
                          0
                          • R Offline
                            R Offline
                            ras123
                            wrote on last edited by
                            #13

                            No, I am doing one by one, do I need to implement all ?

                            1 Reply Last reply
                            0
                            • A Offline
                              A Offline
                              andre
                              wrote on last edited by
                              #14

                              Well, what do you think happens if you model tells the view that there are ten rows, and the view then tries to actually get the data for those rows?

                              1 Reply Last reply
                              0
                              • R Offline
                                R Offline
                                ras123
                                wrote on last edited by
                                #15

                                Hi,
                                Too works to get a result, I think it is better to use insertRows() on proxyModel, because I don't know how to set ModelIndex for the new row, here is my code.
                                @Qt::ItemFlags MyProxyModel::flags(const QModelIndex &index) const
                                {
                                Qt::ItemFlags flags = QIdentityProxyModel::flags(index);
                                if (index.column() > 0)
                                flags |= Qt::ItemIsEditable;
                                return flags;
                                }

                                int MyProxyModel::rowCount(const QModelIndex &parent) const
                                {
                                return QIdentityProxyModel::rowCount()+1;
                                }

                                QVariant MyProxyModel::data(const QModelIndex &index, int role) const
                                {
                                if(index.row() < QIdentityProxyModel::rowCount())
                                return QIdentityProxyModel::data(index, role);
                                return QVariant();
                                }

                                bool MyProxyModel::setData(const QModelIndex &index, const QVariant &value, int role)
                                {
                                if(index.row() < QIdentityProxyModel::rowCount())
                                return QIdentityProxyModel::setData(index, value, role);

                                return true;
                                

                                }

                                QModelIndex MyProxyModel::index(int row, int column, const QModelIndex &parent) const
                                {
                                return QModelIndex(parent);
                                }@

                                It returns all blank table

                                1 Reply Last reply
                                0
                                • A Offline
                                  A Offline
                                  andre
                                  wrote on last edited by
                                  #16

                                  The (main) problem is in the implementation of index. It always returns the same index, for each item, and an invalid one at that.

                                  Did you read the documentation for QAbstractItemModel::index()? It states:
                                  [quote]When reimplementing this function in a subclass, call createIndex() to generate model indexes that other components can use to refer to items in your model.[/quote]

                                  However, even here, you could re-use the base class implementation for all but the last row.

                                  1 Reply Last reply
                                  0
                                  • R Offline
                                    R Offline
                                    ras123
                                    wrote on last edited by
                                    #17

                                    Sorry I give up.
                                    @Qt::ItemFlags MyProxyModel::flags(const QModelIndex &index) const
                                    {
                                    Qt::ItemFlags flags = QIdentityProxyModel::flags(index);
                                    if (index.column() > 0)
                                    flags |= Qt::ItemIsEditable;
                                    return flags;
                                    }

                                    int MyProxyModel::rowCount(const QModelIndex &parent) const
                                    {
                                    return QIdentityProxyModel::rowCount()+1;
                                    }

                                    QVariant MyProxyModel::data(const QModelIndex &index, int role) const
                                    {
                                    return QIdentityProxyModel::data(index, role);
                                    }

                                    bool MyProxyModel::setData(const QModelIndex &index, const QVariant &value, int role)
                                    {
                                    return QIdentityProxyModel::setData(index, value, role);

                                    }

                                    QModelIndex MyProxyModel::index(int row, int column, const QModelIndex &parent) const
                                    {
                                    return createIndex(row, column);
                                    }@

                                    It displayed database data correctly. But newly entered values disappears as field changes. So can I use
                                    @ int row = proxyModel->rowCount();
                                    proxyModel->insertRow(row);@

                                    Are we coding to get the same result?

                                    1 Reply Last reply
                                    0
                                    • A Offline
                                      A Offline
                                      andre
                                      wrote on last edited by
                                      #18

                                      Nowhere in your reimplementations are you handling the additional row, except in the rowCount() method. No wonder it doesn't work.

                                      1 Reply Last reply
                                      0
                                      • S Offline
                                        S Offline
                                        Sisamon
                                        wrote on last edited by
                                        #19

                                        I realize this thread has been dead for some time, I would like to understand how can you return an index to row count()+1
                                        I assume it should be something like (sorry translating from Python):
                                        @QModelIndex MyProxyModel::index(int row, int column, const QModelIndex &parent) const
                                        {
                                        if (row == super(addItemProxyModel, self).rowCount())
                                        return super(addItemProxyModel, self).createIndex(row, column, 0)
                                        else:
                                        return index(row, column, parent)
                                        }@
                                        But then you are returning a reference to a row that does not exist anywhere in the model, as you return it on the fly with data()
                                        @QVariant MyProxyModel::data(const QModelIndex &index, int role) const
                                        {
                                        if (not index.isValid() or not (0 <= index.row() <= super(addItemProxyModel, self).rowCount()))
                                        return QVariant();
                                        if index.row == rowCount(index)
                                        if role == Qt.DisplayRole
                                        return QVariant(self.message)
                                        else
                                        return QVariant();
                                        else
                                        return QIdentityProxyModel::data(index, role);
                                        }@

                                        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