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. QStandardItem and default data role
Forum Updated to NodeBB v4.3 + New Features

QStandardItem and default data role

Scheduled Pinned Locked Moved Solved General and Desktop
14 Posts 2 Posters 3.6k 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.
  • JonBJ Online
    JonBJ Online
    JonB
    wrote on last edited by
    #1

    My app uses mostly QSql...Model models but also some QStandardItemModels.

    Whether I like the approach or not, I have gotten used to the SQL stuff where, coming from QAbstractItemModel, they all use:

    QVariant QAbstractItemModel::data(const QModelIndex &index, int role = Qt::DisplayRole) const
    bool QAbstractItemModel::setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole)
    

    i.e. the default roles for data()/setData() are DisplayRole/EditRole respectively.

    While refactoring other people's code, to my surprise I found that in the case of QStandardItemModel it sticks to that, BUT for QStandardItem

    QVariant QStandardItem::data(int role = Qt::UserRole + 1) const
    void QStandardItem::setData(const QVariant &value, int role = Qt::UserRole + 1)
    

    i.e. both use a default of Qt::UserRole + 1.

    Correct me if I'm wrong, because my brain is beginning to hurt here, but this means that:

    standardItemModel.data(standardItemModel.index(row, col))
      !=
    standardItemModel.item(row, col).data()
    

    i.e. QStandardItemModel::data()/setData() use different default roles from QStandardItem::data()/setData(). With the code I am looking at mixing these two legitimate ways of addressing QStandardItem items it's getting very hairy... :(

    What's going on here? This is a really bad idea :( Why is QStandardItem defaulting differently from everything else, is it just to confuse me?

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

      Because QStandardItemModel + QStandardItem is a convenience class and already provides access to Qt::DisplayRole and others via custom functions (setFont, setIcon, setText, setToolTip). There is no need to use QStandardItemModel::data() at all.

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

      JonBJ 1 Reply Last reply
      2
      • Christian EhrlicherC Christian Ehrlicher

        Because QStandardItemModel + QStandardItem is a convenience class and already provides access to Qt::DisplayRole and others via custom functions (setFont, setIcon, setText, setToolTip). There is no need to use QStandardItemModel::data() at all.

        JonBJ Online
        JonBJ Online
        JonB
        wrote on last edited by JonB
        #3

        @Christian-Ehrlicher
        Before I comment on what the problems are, did you mis-type:

        There is no need to use QStandardItemModel::data() at all.

        Did you mean QStandardItem:data() instead of QStandardItemModel::data()? Or what?

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

          @JonB: It's from QAbstractItemModel::data().

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

          JonBJ 1 Reply Last reply
          0
          • Christian EhrlicherC Christian Ehrlicher

            @JonB: It's from QAbstractItemModel::data().

            JonBJ Online
            JonBJ Online
            JonB
            wrote on last edited by JonB
            #5

            @Christian-Ehrlicher
            I do not understand what you are talking about now. (Btw, yes, I know what is derived from what.) As I have said, there are two ways at getting at a standard model items' data:

            1. standardItemModel.data(standardItemModel.index(row, col))
            
            2. standardItemModel.item(row, col).data()
            

            The first is going via QStandardItemModel, the second via QStandardItem. Agreed? And you would assume they both return the same result, agreed? Well, they don't, because of the default role difference.

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

              @JonB said in QStandardItem and default data role:

              And you would assume they both return the same result, agreed?

              No, I don't agree here.
              Since QStandardItemModel is a convenience class you should also stick at the convenience way on accessing the data via the QStandardModelItem and it's functions I wrote above.

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

              JonBJ 1 Reply Last reply
              0
              • Christian EhrlicherC Christian Ehrlicher

                @JonB said in QStandardItem and default data role:

                And you would assume they both return the same result, agreed?

                No, I don't agree here.
                Since QStandardItemModel is a convenience class you should also stick at the convenience way on accessing the data via the QStandardModelItem and it's functions I wrote above.

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

                @Christian-Ehrlicher
                Right then.

                First of all I'm not interested in any of setFont, setIcon, setToolTip. What I am interested in is the different data which can be stored/returned via setData/data() using the two roles DisplayRole vs EditRole.

                And second, it's all very well saying what one "should stick at", but I am talking about reviewing code written by someone else. When storing/retrieving data in a QStandardItemModel, that person has sometimes used QStandardItemModel::set/Data() directly and sometimes used QStandardItemModel::item(...).set/Data(). Both of those address the same QStandardItem in the model. You (I) would have thought they would set/return the same value. But they do not, because of the difference in the default roles between the two seemingly-identical approaches. So the code I'm reviewing is not right. :( Which is what I am whinging about.

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

                  Yes, relying on the default value isn't that good sometimes... even in the qt module tests there were some issues with the default role which only came up after a change in the convenience QTable/Tree/ListWidget classes to publish the modified roles instead no roles (3rd argument in dataChanged())

                  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
                  • Christian EhrlicherC Offline
                    Christian EhrlicherC Offline
                    Christian Ehrlicher
                    Lifetime Qt Champion
                    wrote on last edited by
                    #9

                    Don't know if this works in Python but I C++ I would derive from QStandardItemModel, make data() private and replace all occurrences of QStandardItemModel with the new class. Then I would get a compiler warning as soon as DerivedClass::data() is called.

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

                    JonBJ 2 Replies Last reply
                    0
                    • Christian EhrlicherC Christian Ehrlicher

                      Don't know if this works in Python but I C++ I would derive from QStandardItemModel, make data() private and replace all occurrences of QStandardItemModel with the new class. Then I would get a compiler warning as soon as DerivedClass::data() is called.

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

                      @Christian-Ehrlicher

                      make data() private

                      Nope, this is Python! Everything is public. Even if it's private it's still public. Unless Qt chose to rename the data/setData() methods to __data()/__setData(). And even then they'd still be public really.

                      Then I would get a compiler warning as soon as DerivedClass::data() is called.

                      This is Python, don't make me laugh ;-) Compiler? Warning?

                      :)

                      1 Reply Last reply
                      0
                      • Christian EhrlicherC Christian Ehrlicher

                        Don't know if this works in Python but I C++ I would derive from QStandardItemModel, make data() private and replace all occurrences of QStandardItemModel with the new class. Then I would get a compiler warning as soon as DerivedClass::data() is called.

                        JonBJ Online
                        JonBJ Online
                        JonB
                        wrote on last edited by JonB
                        #11

                        @Christian-Ehrlicher
                        But here's what I don't get even if I tried to adopt what you say. Again, please correct me if I'm wrong.

                        All these models are heavily used by the code from QTableViews etc. The whole point is that uses the data()/setData() methods (with defaults DisplayRole/EditRole). So surely if you hide those two methods with privacy you won't be able to use your derived class from table views, no?

                        Apparently unlike you, I do not see the problem in QStandardItemModel::data()'s behaviour. I see the problem in the non-consistent QStandardItem::data()'s behaviour. I'm not sure whether that is getting across.

                        In the code, at line #10 data is being set via

                        standardItemModel.setData(standardItemModel.index(0, 0), foo)
                        

                        Then at line #10,000 data is being read back from the same item via

                        bar = standardItemModel.item(0, 0).data()
                        

                        I expect foo & bar to be the same value. But they are not.

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

                          @JonB said in QStandardItem and default data role:

                          But they are not.

                          Correct, because you're mixing the convenience class with the underlying QAIM.

                          --> standardItemModel.item(0,0)->setData(foo) is what you want if you want to use QStandardItemModel::data() without a parameter.
                          Or, as I said before - don't rely on default parameters at all.

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

                          JonBJ 1 Reply Last reply
                          0
                          • Christian EhrlicherC Christian Ehrlicher

                            @JonB said in QStandardItem and default data role:

                            But they are not.

                            Correct, because you're mixing the convenience class with the underlying QAIM.

                            --> standardItemModel.item(0,0)->setData(foo) is what you want if you want to use QStandardItemModel::data() without a parameter.
                            Or, as I said before - don't rely on default parameters at all.

                            JonBJ Online
                            JonBJ Online
                            JonB
                            wrote on last edited by JonB
                            #13

                            @Christian-Ehrlicher
                            No! Unless yet again we are misunderstanding each other :)

                            Let's be clear: foo was my data value, not a role. Then quoting from what you have just written:

                            standardItemModel.item(0,0)->setData(foo)
                            

                            This is using QStandardItemModel::item()::setData(). QStandardItemModel::item() is a QStandardItem. QStandardItem::setData() has default parameter int role = Qt::UserRole + 1.

                            QStandardItemModel::data() 
                            

                            This is using QStandardItemModel::data() (not QStandardItem::data()), which has default parameter int role = Qt::DisplayRole.

                            For consistency --- and assuming you are not passing any role explicitly --- one must either stick to doing data operations via paired QStandardItemModel::set/Data(index(0, 0)) or via paired QStandardItemModel::item(0, 0)::set/Data(). Your example just broke that consistency, it's using one of each! The code I am looking at (not written by me, who now knows better) has equally broken that consistent pairing, and so is wrong. Hence I am now spending hours tracking down precisely where current code accesses data directly off QStandardItemModel vs via QStandardItemModel::item().

                            My original question was: to avoid just this, why [there must be a reason] does QStandardItem::set/Data() use UserRole+1, instead of DisplayRole/EditRole as the respective role defaults just like say QStandardItemModel::set/Data() does and same for other models? Then I wouldn't be crying in a bath over this....

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

                              QStandardItemModel is a convenience function which should be filled with QStandardItem::data()/setData(). If you mix it with QAbstractItemView::setData() then you also should use the corresponding QAIV::data() function.

                              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

                              • Login

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