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. How to update values in a custom model after editing

How to update values in a custom model after editing

Scheduled Pinned Locked Moved Unsolved General and Desktop
10 Posts 3 Posters 2.0k 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.
  • D Offline
    D Offline
    DaveK 0
    wrote on 28 Jul 2018, 22:30 last edited by DaveK 0
    #1

    I am trying to implement something similar to the example http://doc.qt.io/qt-5/qtsql-querymodel-example.html

    In this example, a custom model is created based off QSqlQueryModel that makes some columns editable. After data is edited by the user the model runs a query to update the database with the new value, and then refreshes the model so that the user can see it has been updated.

    What I would like to do is - Instead of running a query to update the data in a database, I would like to update the data ONLY in the model (and leave the database as is). How can I update my model within the setData function?

    Here is my implementation, I would like to update column 0 with whatever data the user entered, so that is persists in the model.

    bool MyModel::setData(const QModelIndex &index, const QVariant &value, int /* role */)
    {
    	if (index.column() != 0)
    		return false;
    
    	bool ok = false;
    	if (index.column() == 0) {
    		ok = setQtyToShip(index, value.toString());
    	}
    	return ok;
    }
    
    bool MyModel::setQtyToShip(const QModelIndex &index, const QString &value)
    {
    	// TODO: Update the cell at index with the data the user entered.
    	return true;
    }
    
    1 Reply Last reply
    0
    • C Offline
      C Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on 29 Jul 2018, 06:20 last edited by
      #2

      How looks your data() function? Where does it get it's values from?

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      1 Reply Last reply
      1
      • D Offline
        D Offline
        DaveK 0
        wrote on 29 Jul 2018, 13:03 last edited by
        #3

        I did not override the data() function. So it should look the same as it does when it is inherited QSqlQueryModel, from QAbstractItemModel.

        Do I need to re-implement the data() function?

        1 Reply Last reply
        0
        • C Offline
          C Offline
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on 29 Jul 2018, 15:02 last edited by
          #4

          Yes, you must reimplement data() when you want to display your custom values.

          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
          Visit the Qt Academy at https://academy.qt.io/catalog

          D 1 Reply Last reply 29 Jul 2018, 15:49
          1
          • C Christian Ehrlicher
            29 Jul 2018, 15:02

            Yes, you must reimplement data() when you want to display your custom values.

            D Offline
            D Offline
            DaveK 0
            wrote on 29 Jul 2018, 15:49 last edited by
            #5

            @Christian-Ehrlicher What should I reimplement it with?

            1 Reply Last reply
            0
            • C Offline
              C Offline
              Christian Ehrlicher
              Lifetime Qt Champion
              wrote on 29 Jul 2018, 16:05 last edited by
              #6

              Since you want to show custom data, you should remember it when set via setData() and return this value in data() for the requested cell. If you have no custom data, simply call the base class to retrieve it from the database.

              Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
              Visit the Qt Academy at https://academy.qt.io/catalog

              D 1 Reply Last reply 29 Jul 2018, 16:27
              2
              • C Christian Ehrlicher
                29 Jul 2018, 16:05

                Since you want to show custom data, you should remember it when set via setData() and return this value in data() for the requested cell. If you have no custom data, simply call the base class to retrieve it from the database.

                D Offline
                D Offline
                DaveK 0
                wrote on 29 Jul 2018, 16:27 last edited by
                #7

                @Christian-Ehrlicher Just to make sure I understand... What I would like to do is:

                1. Retrieve info from a db, and populate that into a table.
                2. Allow the user to edit values in a particular column.
                3. If a user makes changes to that column, save the change value in the model to be accessed later (not saved in the DB).

                So to do this I should:

                1. Not actually modify the value already stored in the model.
                2. Create a member variable in my model, specifically to hold changed values. (Possibly a QMap<int, int> where the 1stint is the row#, and the 2nd int is my user changed value as it happens to be an int in this case)?
                3. In my re-implemented setData() function, I would add a value to the QMap with the row# and new value modified by the user.
                4. in my re-implemented data() function, I would recall a value from my member QMap (if it exists), or the data in the model if it does not.

                Is that what you mean?

                1 Reply Last reply
                1
                • C Offline
                  C Offline
                  Christian Ehrlicher
                  Lifetime Qt Champion
                  wrote on 29 Jul 2018, 17:07 last edited by
                  #8

                  This is the way I would do it, yes.

                  Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                  Visit the Qt Academy at https://academy.qt.io/catalog

                  D 1 Reply Last reply 7 Aug 2018, 00:33
                  1
                  • C Christian Ehrlicher
                    29 Jul 2018, 17:07

                    This is the way I would do it, yes.

                    D Offline
                    D Offline
                    DaveK 0
                    wrote on 7 Aug 2018, 00:33 last edited by DaveK 0 8 Jul 2018, 02:32
                    #9

                    @Christian-Ehrlicher So I have added the following to my header file:

                    private:
                    	QMap<int, int> m_myMap; 
                    

                    And re-implemented the following:

                    bool MyModel::setData(const QModelIndex &index, const QVariant &value, int /* role */)
                    {
                    	// Only "Qty To Ship" (column 0) is editable.
                    	if (index.column() != 0)
                    		return false;
                    
                    	bool ok = false;
                    	if (index.column() == 0) {
                    		ok = m_myMap[index.row()] = value.toInt();
                    	}
                    
                    	return ok;
                    }
                    
                    
                    QVariant MyModel::data(const QModelIndex &item, int role)
                    {
                    	if( item.column() - 1 == 0)  // I'm not sure why item.column() returns 1.  For now I am just subtracting 1 so that it runs the following:
                    	{
                    		QVariant v = m_myMap[item.row()];
                    		return v;
                    	} else {
                    		return itemData(item).value(0);
                    	}
                    }
                    

                    I can see that my QMap<int, int> is storing the value from the cell for each row, and data() is returning a QVariant - but I still do not see the value shown in my table view. What am I missing from my ::data() function?

                    JonBJ 1 Reply Last reply 7 Aug 2018, 16:50
                    0
                    • D DaveK 0
                      7 Aug 2018, 00:33

                      @Christian-Ehrlicher So I have added the following to my header file:

                      private:
                      	QMap<int, int> m_myMap; 
                      

                      And re-implemented the following:

                      bool MyModel::setData(const QModelIndex &index, const QVariant &value, int /* role */)
                      {
                      	// Only "Qty To Ship" (column 0) is editable.
                      	if (index.column() != 0)
                      		return false;
                      
                      	bool ok = false;
                      	if (index.column() == 0) {
                      		ok = m_myMap[index.row()] = value.toInt();
                      	}
                      
                      	return ok;
                      }
                      
                      
                      QVariant MyModel::data(const QModelIndex &item, int role)
                      {
                      	if( item.column() - 1 == 0)  // I'm not sure why item.column() returns 1.  For now I am just subtracting 1 so that it runs the following:
                      	{
                      		QVariant v = m_myMap[item.row()];
                      		return v;
                      	} else {
                      		return itemData(item).value(0);
                      	}
                      }
                      

                      I can see that my QMap<int, int> is storing the value from the cell for each row, and data() is returning a QVariant - but I still do not see the value shown in my table view. What am I missing from my ::data() function?

                      JonBJ Offline
                      JonBJ Offline
                      JonB
                      wrote on 7 Aug 2018, 16:50 last edited by
                      #10

                      @DaveK-0

                      1. I don't understand your "problem" comment in your code. You need to sort out consistent column numbers. QModelIndex::column() will have the same value for the same cell in both data() & setData(), you seem to be accessing the wrong column.

                      2. You're always setting/returning your data value in setData()/data() regardless of role. You cannot afford to do that. You need to examine the role and call the base implementation of setData()/data() in those cases not setting/requesting the actual data value.

                      I would guess one or other (or both) of the above is going to stop you seeing anything meaningful in your attached QTableView.

                      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