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. Restrict setting inapropriate data to the model with delegates (like text data to spinbox delegate)
Forum Updated to NodeBB v4.3 + New Features

Restrict setting inapropriate data to the model with delegates (like text data to spinbox delegate)

Scheduled Pinned Locked Moved Solved General and Desktop
13 Posts 3 Posters 1.1k 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.
  • Please_Help_me_DP Offline
    Please_Help_me_DP Offline
    Please_Help_me_D
    wrote on last edited by
    #1

    Hi,

    I have QTableView with QStandardItemModel . In some columns I set different delegates like delegate for QComboBox or QSpinBox.
    I added functionality to copy/past data that uses QStandardItemModel::setData().

    The problem is that it allows to copy for example text in column where I set spinbox delegate. Thus it is possible to see that column with spinbox delegate has textual data. This is not good .

    How can I set data to the model and check if data is appropriate for the column? Or at least set data to the model and then update this model to remove inapropriate data in cells?

    1 Reply Last reply
    0
    • Please_Help_me_DP Offline
      Please_Help_me_DP Offline
      Please_Help_me_D
      wrote on last edited by
      #13

      I've found a solution for my case.
      After paste() command wich is in void TableView::keyPressEvent(QKeyEvent *event) I do:

          setCurrentIndex(index); // set current index
          edit(index); // starts editing of item
      

      Whenever edit(..) is invoked a delegate is created and if displayed data is invalid then it removes it. And if data is acceptable then delegate accepts it.
      `setCurrentIndex(..)' is needed as only current indexes can be editable

      1 Reply Last reply
      0
      • Christian EhrlicherC Online
        Christian EhrlicherC Online
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote on last edited by
        #2

        @Please_Help_me_D said in Restrict setting inapropriate data to the model with delegates (like text data to spinbox delegate):

        The problem is that it allows to copy for example text in column where I set spinbox delegate. Thus it is possible to see that column with spinbox delegate has textual data. This is not good .

        Can you explain this more? How do you copy text when there is a spinbox?

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

        Please_Help_me_DP 1 Reply Last reply
        1
        • Christian EhrlicherC Christian Ehrlicher

          @Please_Help_me_D said in Restrict setting inapropriate data to the model with delegates (like text data to spinbox delegate):

          The problem is that it allows to copy for example text in column where I set spinbox delegate. Thus it is possible to see that column with spinbox delegate has textual data. This is not good .

          Can you explain this more? How do you copy text when there is a spinbox?

          Please_Help_me_DP Offline
          Please_Help_me_DP Offline
          Please_Help_me_D
          wrote on last edited by
          #3

          @Christian-Ehrlicher Hi
          Here is the picture:
          ed31b619-e358-440b-8749-0384a63748c3-image.png

          Actually I can set any data to the cell via model->setData() and no matter whether there is a delegate or not the cell will accept this data. But after I double click on the cell then the can either stay or it will be removed if data is inapropriate for the delegate.

          I just remembered one thing: I have both proxy (QSortFilterProxyModel) and QStandardItemModel as a source model. I implemented copy/past according to this post: https://www.walletfox.com/course/qtableviewcopypaste.php
          I think setData() is applied to the proxy model (according the post)

          JonBJ 1 Reply Last reply
          0
          • Please_Help_me_DP Please_Help_me_D

            @Christian-Ehrlicher Hi
            Here is the picture:
            ed31b619-e358-440b-8749-0384a63748c3-image.png

            Actually I can set any data to the cell via model->setData() and no matter whether there is a delegate or not the cell will accept this data. But after I double click on the cell then the can either stay or it will be removed if data is inapropriate for the delegate.

            I just remembered one thing: I have both proxy (QSortFilterProxyModel) and QStandardItemModel as a source model. I implemented copy/past according to this post: https://www.walletfox.com/course/qtableviewcopypaste.php
            I think setData() is applied to the proxy model (according the post)

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

            @Please_Help_me_D said in Restrict setting inapropriate data to the model with delegates (like text data to spinbox delegate):

            Actually I can set any data to the cell via model->setData()

            I'm not with you (unless I misunderstand): it is your job to write code in setData() to only accept whatever you wish to be acceptable/valid for the index/item (return false if not). Doesn't matter where the input data emanates from: input widgets, paste, whatever. Also, I don't get why you show a column containing letters, and have a delegate which is a spinbox, one of those two seems inconsistent.

            Christian EhrlicherC 1 Reply Last reply
            0
            • JonBJ JonB

              @Please_Help_me_D said in Restrict setting inapropriate data to the model with delegates (like text data to spinbox delegate):

              Actually I can set any data to the cell via model->setData()

              I'm not with you (unless I misunderstand): it is your job to write code in setData() to only accept whatever you wish to be acceptable/valid for the index/item (return false if not). Doesn't matter where the input data emanates from: input widgets, paste, whatever. Also, I don't get why you show a column containing letters, and have a delegate which is a spinbox, one of those two seems inconsistent.

              Christian EhrlicherC Online
              Christian EhrlicherC Online
              Christian Ehrlicher
              Lifetime Qt Champion
              wrote on last edited by
              #5

              @JonB said in Restrict setting inapropriate data to the model with delegates (like text data to spinbox delegate):

              Also, I don't get why you show a column containing letters, and have a delegate which is a spinbox, one of those two seems inconsistent.

              Correct, the data is absolutely wrong - why should I use a spinbox in a textual field?

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

              Please_Help_me_DP 1 Reply Last reply
              0
              • Christian EhrlicherC Christian Ehrlicher

                @JonB said in Restrict setting inapropriate data to the model with delegates (like text data to spinbox delegate):

                Also, I don't get why you show a column containing letters, and have a delegate which is a spinbox, one of those two seems inconsistent.

                Correct, the data is absolutely wrong - why should I use a spinbox in a textual field?

                Please_Help_me_DP Offline
                Please_Help_me_DP Offline
                Please_Help_me_D
                wrote on last edited by Please_Help_me_D
                #6

                @Christian-Ehrlicher said in Restrict setting inapropriate data to the model with delegates (like text data to spinbox delegate):

                Also, I don't get why you show a column containing letters, and have a delegate which is a spinbox, one of those two seems inconsistent.

                I think you don't understand the problem.

                I need to forbid to paste textual data to the column where data is supposed to be numbers (for example where spinbox delegate is). If I have spinbox delegate in column "coord_1 col" then I want that this column accepts only numbers acceptable in spinbox. I don't understand how to do that?

                @JonB said in Restrict setting inapropriate data to the model with delegates (like text data to spinbox delegate):

                I'm not with you (unless I misunderstand): it is your job to write code in setData() to only accept whatever you wish to be acceptable/valid for the index/item (return false if not).

                Well I think the same but: copy/past are methods of a QTableView, delegates are also available from QTableView and setData(...) is a model's method.
                The only way I see how to achieve my goal is:
                implement new model's method like setFilteredData(QVariant var, Qt::role). This method should get treeView and from this treeView it should check whether there is delegate. If there is then it should set data via QAbstractItemDelegate::setEditorData(...) and if there is not then I can set data via setData(...).

                I think my logic is uneffective because I need to get tableView from model. Usually I would implement it from searching through parents of model and I don't like it as I'm not shure whether I can always find some widget through parent in all possible cases.

                Probably you can see other ways of doing this?

                JonBJ 1 Reply Last reply
                0
                • Please_Help_me_DP Please_Help_me_D

                  @Christian-Ehrlicher said in Restrict setting inapropriate data to the model with delegates (like text data to spinbox delegate):

                  Also, I don't get why you show a column containing letters, and have a delegate which is a spinbox, one of those two seems inconsistent.

                  I think you don't understand the problem.

                  I need to forbid to paste textual data to the column where data is supposed to be numbers (for example where spinbox delegate is). If I have spinbox delegate in column "coord_1 col" then I want that this column accepts only numbers acceptable in spinbox. I don't understand how to do that?

                  @JonB said in Restrict setting inapropriate data to the model with delegates (like text data to spinbox delegate):

                  I'm not with you (unless I misunderstand): it is your job to write code in setData() to only accept whatever you wish to be acceptable/valid for the index/item (return false if not).

                  Well I think the same but: copy/past are methods of a QTableView, delegates are also available from QTableView and setData(...) is a model's method.
                  The only way I see how to achieve my goal is:
                  implement new model's method like setFilteredData(QVariant var, Qt::role). This method should get treeView and from this treeView it should check whether there is delegate. If there is then it should set data via QAbstractItemDelegate::setEditorData(...) and if there is not then I can set data via setData(...).

                  I think my logic is uneffective because I need to get tableView from model. Usually I would implement it from searching through parents of model and I don't like it as I'm not shure whether I can always find some widget through parent in all possible cases.

                  Probably you can see other ways of doing this?

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

                  @Please_Help_me_D said in Restrict setting inapropriate data to the model with delegates (like text data to spinbox delegate):

                  I think you don't understand the problem.

                  I think actually I do :)

                  Like I said, it is your job to write the necessary validation/rejection logic here. It doesn't matter that paste is functionality is in the view. The view cannot put data into the model which the model does not accept, and it is the model's job to reject any illegal data, not the view's. This is good logic, because you should not rely on the assumption that data can only be presented to the model from the view: assume that there is no view, or that the user by-passes any view, and write your model logic accordingly.

                  You should subclass your QStandardItemModel if necessary if you need to override its setData() (e.g. for validation), and write your logic there. Maybe the subclassing is the bit you are missing, if you use QStandardItemModel directly. Any QItemDelegate::setModelData() will go via that, so you'll get it rejected by the view editor as a bonus.

                  implement new model's method like [...]
                  This method should get treeView and from this treeView it should check whether there is delegate.
                  If there is then it should set data via QAbstractItemDelegate::setEditorData(...) and if there is not then I can set data via setData(...).

                  Absolutely not! Models should never know about views or delegates. (BTW, separately, I think you are confusing setEditorData() with setModelData().) Your "because I need to get tableView from model. ": except in exceptional circumstances, you should never try to get views from model, and there should not be any reason to want to do so.

                  Like I say, maybe if you realize that can subclass your current QStandardItemModel, and that will allow to override setData() and return false on invalid data, it will all become clearer.

                  Please_Help_me_DP 1 Reply Last reply
                  0
                  • JonBJ JonB

                    @Please_Help_me_D said in Restrict setting inapropriate data to the model with delegates (like text data to spinbox delegate):

                    I think you don't understand the problem.

                    I think actually I do :)

                    Like I said, it is your job to write the necessary validation/rejection logic here. It doesn't matter that paste is functionality is in the view. The view cannot put data into the model which the model does not accept, and it is the model's job to reject any illegal data, not the view's. This is good logic, because you should not rely on the assumption that data can only be presented to the model from the view: assume that there is no view, or that the user by-passes any view, and write your model logic accordingly.

                    You should subclass your QStandardItemModel if necessary if you need to override its setData() (e.g. for validation), and write your logic there. Maybe the subclassing is the bit you are missing, if you use QStandardItemModel directly. Any QItemDelegate::setModelData() will go via that, so you'll get it rejected by the view editor as a bonus.

                    implement new model's method like [...]
                    This method should get treeView and from this treeView it should check whether there is delegate.
                    If there is then it should set data via QAbstractItemDelegate::setEditorData(...) and if there is not then I can set data via setData(...).

                    Absolutely not! Models should never know about views or delegates. (BTW, separately, I think you are confusing setEditorData() with setModelData().) Your "because I need to get tableView from model. ": except in exceptional circumstances, you should never try to get views from model, and there should not be any reason to want to do so.

                    Like I say, maybe if you realize that can subclass your current QStandardItemModel, and that will allow to override setData() and return false on invalid data, it will all become clearer.

                    Please_Help_me_DP Offline
                    Please_Help_me_DP Offline
                    Please_Help_me_D
                    wrote on last edited by
                    #8

                    @JonB said in Restrict setting inapropriate data to the model with delegates (like text data to spinbox delegate):

                    Like I say, maybe if you realize that can subclass your current QStandardItemModel, and that will allow to override setData() and return false on invalid data, it will all become clearer.

                    If I understand you I need to do all the checks inside model's setData(..). But in this case I will have two steps of checking:

                    1. in delegate
                    2. in model

                    And those those steps should do the same job. I don't think that this is good solution.

                    For example for third column I set spinboxDelegate which accepts only integers. This delegate is available from treeView.
                    To forbid pasting textual data to the third colum I implement filtering in MyModel->setData(QVariant data) which should check whether data contains only integer.
                    Or I misunderstand something?

                    By the way my treeView has different delegates for different columns, there are: spinbox, doubleSpinbox, comboWidget

                    JonBJ 1 Reply Last reply
                    0
                    • Christian EhrlicherC Online
                      Christian EhrlicherC Online
                      Christian Ehrlicher
                      Lifetime Qt Champion
                      wrote on last edited by
                      #9

                      @Please_Help_me_D said in Restrict setting inapropriate data to the model with delegates (like text data to spinbox delegate):

                      To forbid pasting textual data to the third colum

                      I still don't understand - if there is a spinbox delegate you can't paste anything but numbers in there...

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

                      Please_Help_me_DP 1 Reply Last reply
                      0
                      • Please_Help_me_DP Please_Help_me_D

                        @JonB said in Restrict setting inapropriate data to the model with delegates (like text data to spinbox delegate):

                        Like I say, maybe if you realize that can subclass your current QStandardItemModel, and that will allow to override setData() and return false on invalid data, it will all become clearer.

                        If I understand you I need to do all the checks inside model's setData(..). But in this case I will have two steps of checking:

                        1. in delegate
                        2. in model

                        And those those steps should do the same job. I don't think that this is good solution.

                        For example for third column I set spinboxDelegate which accepts only integers. This delegate is available from treeView.
                        To forbid pasting textual data to the third colum I implement filtering in MyModel->setData(QVariant data) which should check whether data contains only integer.
                        Or I misunderstand something?

                        By the way my treeView has different delegates for different columns, there are: spinbox, doubleSpinbox, comboWidget

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

                        @Please_Help_me_D said in Restrict setting inapropriate data to the model with delegates (like text data to spinbox delegate):

                        And those those steps should do the same job. I don't think that this is good solution.

                        Well it's a shame you feel like that, since that is the correct thing to do. Models should always do the correct data validation, always. As I said before, models can receive data without going through a view. The view on top of that, with its own validation, is simply "the icing on the cake", to aid the end user. It is code which fails to validate data in the backed (model), and relies on the front-end (view) to have ensured data is correct/acceptable which potentially leads to half the data problems/attacks/hacks we have in the world....

                        It is possible that you may find some way of sharing the validation code from somewhere common which can be used by both model & view.

                        Also, as I said, the view setting model data should detect rejection from the model's setData() so it can use that in part for its validation purposes.

                        If like you I had data which is of different types for different columns, I either would not go directly through setData() and instead expose typed getters/setters for each column, or I would use my own custom model and not plain QStandardItemModel. It also makes coding easier.

                        Anyway, since you have your own views on what is a good solution, I leave you to decide.

                        1 Reply Last reply
                        0
                        • Christian EhrlicherC Christian Ehrlicher

                          @Please_Help_me_D said in Restrict setting inapropriate data to the model with delegates (like text data to spinbox delegate):

                          To forbid pasting textual data to the third colum

                          I still don't understand - if there is a spinbox delegate you can't paste anything but numbers in there...

                          Please_Help_me_DP Offline
                          Please_Help_me_DP Offline
                          Please_Help_me_D
                          wrote on last edited by
                          #11

                          @Christian-Ehrlicher said in Restrict setting inapropriate data to the model with delegates (like text data to spinbox delegate):

                          I still don't understand - if there is a spinbox delegate you can't paste anything but numbers in there...

                          Actually I can :)
                          Here on the picture is my explanation how I see that:
                          c86df25c-a703-4174-bc85-174aec61a8a2-image.png

                          @JonB thank you for sharing opinion. I decided to take some time to thing about all of this. I should be missing something important

                          1 Reply Last reply
                          0
                          • Christian EhrlicherC Online
                            Christian EhrlicherC Online
                            Christian Ehrlicher
                            Lifetime Qt Champion
                            wrote on last edited by
                            #12

                            You're responsible by yourself to set the correct data to your model.

                            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
                            0
                            • Please_Help_me_DP Offline
                              Please_Help_me_DP Offline
                              Please_Help_me_D
                              wrote on last edited by
                              #13

                              I've found a solution for my case.
                              After paste() command wich is in void TableView::keyPressEvent(QKeyEvent *event) I do:

                                  setCurrentIndex(index); // set current index
                                  edit(index); // starts editing of item
                              

                              Whenever edit(..) is invoked a delegate is created and if displayed data is invalid then it removes it. And if data is acceptable then delegate accepts it.
                              `setCurrentIndex(..)' is needed as only current indexes can be editable

                              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