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. Saving and discarding QAbstractTableModel in a dialog
Forum Updated to NodeBB v4.3 + New Features

Saving and discarding QAbstractTableModel in a dialog

Scheduled Pinned Locked Moved Unsolved General and Desktop
8 Posts 4 Posters 721 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.
  • N Offline
    N Offline
    Nekreg45
    wrote on last edited by
    #1

    Hi, I am having trouble with having good practices for saving and discarding changes. I want to be able to open a dialog make changes to a table in a TableView and decide whether to keep the changes or not when exit the dialog.

    Since the TableView modifies your existing data automatically, I had to come up with a way to prevent that. In a setup call to the dialog class, I passed in a pointer of the table model, stored it as a member variable, and made its own copy. The TableView would set its model to the copy. If "Save" is pressed, then I have the stored pointer of the table model clone the copy. If "Cancel" is pressed, then I simply do nothing and close the dialog.

    This method works in general, but has become more complicated because my tables are inheriting from a base class. Therefore, it has become difficult to make a local copy because I need to know what is the derived class. This has led to creating additional classes for every type of table just to use this dialog.

    Does anybody have a simpler solution to the problem of preventing a TableView from applying its changes until the user accepts them?

    Thanks!

    JonBJ 1 Reply Last reply
    0
    • N Nekreg45

      Hi, I am having trouble with having good practices for saving and discarding changes. I want to be able to open a dialog make changes to a table in a TableView and decide whether to keep the changes or not when exit the dialog.

      Since the TableView modifies your existing data automatically, I had to come up with a way to prevent that. In a setup call to the dialog class, I passed in a pointer of the table model, stored it as a member variable, and made its own copy. The TableView would set its model to the copy. If "Save" is pressed, then I have the stored pointer of the table model clone the copy. If "Cancel" is pressed, then I simply do nothing and close the dialog.

      This method works in general, but has become more complicated because my tables are inheriting from a base class. Therefore, it has become difficult to make a local copy because I need to know what is the derived class. This has led to creating additional classes for every type of table just to use this dialog.

      Does anybody have a simpler solution to the problem of preventing a TableView from applying its changes until the user accepts them?

      Thanks!

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by
      #2

      @Nekreg45 said in Saving and discarding QAbstractTableModel in a dialog:

      Therefore, it has become difficult to make a local copy because I need to know what is the derived class. This has led to creating additional classes for every type of table just to use this dialog.

      Don't try to do the copy this way. Use the inherited data() method: iterate through all the rows & columns calling that.

      1 Reply Last reply
      1
      • mrjjM Offline
        mrjjM Offline
        mrjj
        Lifetime Qt Champion
        wrote on last edited by
        #3

        Hi
        Since its a custom model where you can control everything, could you not
        store the original value in a user role on edit.

        Then if changes are to not be saved, loop over the indexes and restore the values
        for the changed ones. ?

        N 1 Reply Last reply
        3
        • VRoninV Offline
          VRoninV Offline
          VRonin
          wrote on last edited by VRonin
          #4

          You can use RoleMaskProxyModel from this library
          Example:

          QDialog editDialog;
          // create the proxy
          RoleMaskProxyModel* editProxy = new RoleMaskProxyModel(&editDialog);
          editProxy->setSourceModel(model);
          // tell it to intercept all changes to EditRole
          editProxy->addMaskedRole(Qt::EditRole);
          QTableView* editView = new QTableView(&editDialog);
          editView->setModel(editProxy);
          QDialogButtonBox *dialButtons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel ,&editDialog);
          QObject::connect(dialButtons,&QDialogButtonBox::accepted,&editDialog,&QDialog::accept);
          QObject::connect(dialButtons,&QDialogButtonBox::rejected,&editDialog,&QDialog::reject);
          QVBoxLayout* dialLay = new QVBoxLayout(&editDialog);
          dialLay->addWidget(editView);
          dialLay->addWidget(dialButtons);
          if(editDialog.exec()){
          // if the dialog is accepted save the changes back into the model
          	for(int i=0;i<editProxy->rowCount();++i){
          		for(int j=0;j<editProxy->columnCount();++j){
          			model->setData(model->index(i,j),editProxy->index(i,j).data());
          		}
          	}
          }
          

          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
          ~Napoleon Bonaparte

          On a crusade to banish setIndexWidget() from the holy land of Qt

          N 1 Reply Last reply
          3
          • mrjjM mrjj

            Hi
            Since its a custom model where you can control everything, could you not
            store the original value in a user role on edit.

            Then if changes are to not be saved, loop over the indexes and restore the values
            for the changed ones. ?

            N Offline
            N Offline
            Nekreg45
            wrote on last edited by
            #5

            @mrjj Wouldn't this mean that I would have to store two sets of data on my custom model? One that is my "saved" data and the other is "modified but not saved" data?

            I like the idea of being able to custom the data being retrieved vs edited, but it feels wrong to store temporary data for the lifetime of the model.

            mrjjM 1 Reply Last reply
            0
            • VRoninV VRonin

              You can use RoleMaskProxyModel from this library
              Example:

              QDialog editDialog;
              // create the proxy
              RoleMaskProxyModel* editProxy = new RoleMaskProxyModel(&editDialog);
              editProxy->setSourceModel(model);
              // tell it to intercept all changes to EditRole
              editProxy->addMaskedRole(Qt::EditRole);
              QTableView* editView = new QTableView(&editDialog);
              editView->setModel(editProxy);
              QDialogButtonBox *dialButtons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel ,&editDialog);
              QObject::connect(dialButtons,&QDialogButtonBox::accepted,&editDialog,&QDialog::accept);
              QObject::connect(dialButtons,&QDialogButtonBox::rejected,&editDialog,&QDialog::reject);
              QVBoxLayout* dialLay = new QVBoxLayout(&editDialog);
              dialLay->addWidget(editView);
              dialLay->addWidget(dialButtons);
              if(editDialog.exec()){
              // if the dialog is accepted save the changes back into the model
              	for(int i=0;i<editProxy->rowCount();++i){
              		for(int j=0;j<editProxy->columnCount();++j){
              			model->setData(model->index(i,j),editProxy->index(i,j).data());
              		}
              	}
              }
              
              N Offline
              N Offline
              Nekreg45
              wrote on last edited by
              #6

              @VRonin Thanks. What is licensing associated with this library?

              This seems to do what mrjj said, but it uses the proxy model to be a temporary inbetween while it's being used by the view. Does this class make a copy of the original model? Is that the magic?

              VRoninV 1 Reply Last reply
              0
              • N Nekreg45

                @mrjj Wouldn't this mean that I would have to store two sets of data on my custom model? One that is my "saved" data and the other is "modified but not saved" data?

                I like the idea of being able to custom the data being retrieved vs edited, but it feels wrong to store temporary data for the lifetime of the model.

                mrjjM Offline
                mrjjM Offline
                mrjj
                Lifetime Qt Champion
                wrote on last edited by
                #7

                @Nekreg45
                Hi
                well you would store only the modified ones, so might not be that many.
                In any case, we will need some way of storing original values to be able to revert so
                even with other solutions, we still end up with a cloned model or a cache of the value of sorts.

                I would try @VRonin RoleMaskProxyModel as then it will just work without altering your model code.

                1 Reply Last reply
                0
                • N Nekreg45

                  @VRonin Thanks. What is licensing associated with this library?

                  This seems to do what mrjj said, but it uses the proxy model to be a temporary inbetween while it's being used by the view. Does this class make a copy of the original model? Is that the magic?

                  VRoninV Offline
                  VRoninV Offline
                  VRonin
                  wrote on last edited by VRonin
                  #8

                  @Nekreg45 said in Saving and discarding QAbstractTableModel in a dialog:

                  What is licensing associated with this library?

                  Apache 2 (Basically MIT + you have the added protection against patent trolls)

                  Does this class make a copy of the original model? Is that the magic?

                  Nope. It has an internal storage system for data that is "masked", for the rest it just uses the data in the original model (just like QIdentityProxyModel).
                  Then you have the option of discarding the data saved in the proxy model (just destroy the proxy) or feeding it back to the original model (the two for loops at the end in my example)

                  "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                  ~Napoleon Bonaparte

                  On a crusade to banish setIndexWidget() from the holy land of Qt

                  1 Reply Last reply
                  2

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved