Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. model.index() returns wrong class
Forum Updated to NodeBB v4.3 + New Features

model.index() returns wrong class

Scheduled Pinned Locked Moved Solved Qt for Python
11 Posts 2 Posters 1.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.
  • nst0022N Offline
    nst0022N Offline
    nst0022
    wrote on last edited by
    #1

    If you run either this PyQt5 Python script:

    from PyQt5.QtWidgets import QApplication
    from PyQt5.QtWidgets import QTreeView
    from PyQt5.QtCore    import QModelIndex
    from PyQt5.QtGui     import QStandardItem
    from PyQt5.QtGui     import QStandardItemModel
    
    app             = QApplication([])
    treeview1       = QTreeView()
    model           = QStandardItemModel()
    parentModelItem = model.invisibleRootItem()
    standardItem    = QStandardItem('--')
    
    parentModelItem.appendRow((standardItem))
    
    modelIndex      = model.index(0, 0, QModelIndex())
    
    print(type(modelIndex.model()))
    # output: <class 'PyQt5.QtGui.QStandardItemModel'>
    

    or this Pyside2 script:

    from PySide2.QtWidgets import QApplication
    from PySide2.QtWidgets import QTreeView
    from PySide2.QtCore    import QModelIndex
    from PySide2.QtGui     import QStandardItem
    from PySide2.QtGui     import QStandardItemModel
    
    app             = QApplication([])
    treeview1       = QTreeView()
    model           = QStandardItemModel()
    parentModelItem = model.invisibleRootItem()
    standardItem    = QStandardItem('--')
    
    parentModelItem.appendRow((standardItem))
    
    modelIndex      = model.index(0, 0, QModelIndex())
    
    print(type(modelIndex.model()))
    # output: <class 'PySide2.QtGui.QStandardItemModel'>   
    
    

    the result in both cases is that the index() function returns a QStandardItemModel object.

    However, documentation says, the result is a QAbstractItemModel

    The difference is the function signatures:

    (1) index() of QStandardItemModel requires row and column only, while
    (2) index() of QAbstractItemModel requires row, column and parent index

    Only (2) allows a unique access of items in a non-trivial QTreeView.

    As there is no other way to access the current selected treeview item, this appears to be a show stopper.

    Am I doing something wrong?

    /////////////

    Debian 10.10 Buster
    PySide2 5.15.2
    Python 3.7.3

    JonBJ 1 Reply Last reply
    0
    • nst0022N Offline
      nst0022N Offline
      nst0022
      wrote on last edited by
      #7

      Got it.

      However, the result differs from the claimed problem in this thread:

      I have a QTreeView.currenIndex() and wanted to retrieve an item from it, then obtain different data columns from this item, which led to the problem.

      This is all nonsense.

      With a QModelIndex, a column can easily be retrieved with:

      myCurrentIndex.sibling(row, col)
      

      And that's it.

      @JonB: I apologize for having made these waves and thank you for your patient assistance, which helped me find the solution :-).

      JonBJ 1 Reply Last reply
      0
      • nst0022N nst0022

        If you run either this PyQt5 Python script:

        from PyQt5.QtWidgets import QApplication
        from PyQt5.QtWidgets import QTreeView
        from PyQt5.QtCore    import QModelIndex
        from PyQt5.QtGui     import QStandardItem
        from PyQt5.QtGui     import QStandardItemModel
        
        app             = QApplication([])
        treeview1       = QTreeView()
        model           = QStandardItemModel()
        parentModelItem = model.invisibleRootItem()
        standardItem    = QStandardItem('--')
        
        parentModelItem.appendRow((standardItem))
        
        modelIndex      = model.index(0, 0, QModelIndex())
        
        print(type(modelIndex.model()))
        # output: <class 'PyQt5.QtGui.QStandardItemModel'>
        

        or this Pyside2 script:

        from PySide2.QtWidgets import QApplication
        from PySide2.QtWidgets import QTreeView
        from PySide2.QtCore    import QModelIndex
        from PySide2.QtGui     import QStandardItem
        from PySide2.QtGui     import QStandardItemModel
        
        app             = QApplication([])
        treeview1       = QTreeView()
        model           = QStandardItemModel()
        parentModelItem = model.invisibleRootItem()
        standardItem    = QStandardItem('--')
        
        parentModelItem.appendRow((standardItem))
        
        modelIndex      = model.index(0, 0, QModelIndex())
        
        print(type(modelIndex.model()))
        # output: <class 'PySide2.QtGui.QStandardItemModel'>   
        
        

        the result in both cases is that the index() function returns a QStandardItemModel object.

        However, documentation says, the result is a QAbstractItemModel

        The difference is the function signatures:

        (1) index() of QStandardItemModel requires row and column only, while
        (2) index() of QAbstractItemModel requires row, column and parent index

        Only (2) allows a unique access of items in a non-trivial QTreeView.

        As there is no other way to access the current selected treeview item, this appears to be a show stopper.

        Am I doing something wrong?

        /////////////

        Debian 10.10 Buster
        PySide2 5.15.2
        Python 3.7.3

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

        @nst0022
        Hi and welcome.

        Thank you for laying out your question neatly, better than many do here :)

        I can see you know what you're talking about, but I'm struggling to understand what actually goes wrong for you? The method returns a QAbstractItemModel, and the instance is a QStandardItemModel, which inherits from QAbstractItemModel, so what is wrong? I don't recognise your difference in function signatures, QAbstractItemModel.index() takes a parent index defaulting to none and that method is overridden by QStandardItemModel to do whatever extra processing but still with that third parameter. Pass your parent index whenever you have one.

        nst0022N 1 Reply Last reply
        2
        • JonBJ JonB

          @nst0022
          Hi and welcome.

          Thank you for laying out your question neatly, better than many do here :)

          I can see you know what you're talking about, but I'm struggling to understand what actually goes wrong for you? The method returns a QAbstractItemModel, and the instance is a QStandardItemModel, which inherits from QAbstractItemModel, so what is wrong? I don't recognise your difference in function signatures, QAbstractItemModel.index() takes a parent index defaulting to none and that method is overridden by QStandardItemModel to do whatever extra processing but still with that third parameter. Pass your parent index whenever you have one.

          nst0022N Offline
          nst0022N Offline
          nst0022
          wrote on last edited by
          #3

          @JonB: Thanks for your quick and concise reply.

          @JonB said in model.index() returns wrong class:

          Pass your parent index whenever you have one.

          That does not work, I already did that and extended my example above:

          from PySide2.QtWidgets import QApplication
          from PySide2.QtWidgets import QTreeView
          from PySide2.QtCore    import QModelIndex
          from PySide2.QtGui     import QStandardItem
          from PySide2.QtGui     import QStandardItemModel
          
          app              = QApplication([])
          treeview1        = QTreeView()
          model            = QStandardItemModel()
          parentModelItem  = model.invisibleRootItem()
          standardItem     = QStandardItem('--')
          
          parentModelItem.appendRow((standardItem))
          
          modelIndex       = model.index(0, 0, QModelIndex())
          
          #new:
          modelIndexParent = modelIndex.parent()
          item             = modelIndex.model().item(0, 0, modelIndexParent)
          

          The result is:

          python3 bug_1_pyside2_b.py
          Traceback (most recent call last):
            File "bug_1_pyside2_b.py", line 18, in <module>
              item             = modelIndex.model().item(0, 0, modelIndexParent)
          TypeError: PySide2.QtGui.QStandardItemModel.item(): too many arguments
          

          this error message is contrary to:

          @JonB said in model.index() returns wrong class:

          is overridden by QStandardItemModel ... but still with that third parameter

          I guess the third parameter is inadvertently omitted in the implementation of QStandardItemModel.

          JonBJ 1 Reply Last reply
          0
          • nst0022N nst0022

            @JonB: Thanks for your quick and concise reply.

            @JonB said in model.index() returns wrong class:

            Pass your parent index whenever you have one.

            That does not work, I already did that and extended my example above:

            from PySide2.QtWidgets import QApplication
            from PySide2.QtWidgets import QTreeView
            from PySide2.QtCore    import QModelIndex
            from PySide2.QtGui     import QStandardItem
            from PySide2.QtGui     import QStandardItemModel
            
            app              = QApplication([])
            treeview1        = QTreeView()
            model            = QStandardItemModel()
            parentModelItem  = model.invisibleRootItem()
            standardItem     = QStandardItem('--')
            
            parentModelItem.appendRow((standardItem))
            
            modelIndex       = model.index(0, 0, QModelIndex())
            
            #new:
            modelIndexParent = modelIndex.parent()
            item             = modelIndex.model().item(0, 0, modelIndexParent)
            

            The result is:

            python3 bug_1_pyside2_b.py
            Traceback (most recent call last):
              File "bug_1_pyside2_b.py", line 18, in <module>
                item             = modelIndex.model().item(0, 0, modelIndexParent)
            TypeError: PySide2.QtGui.QStandardItemModel.item(): too many arguments
            

            this error message is contrary to:

            @JonB said in model.index() returns wrong class:

            is overridden by QStandardItemModel ... but still with that third parameter

            I guess the third parameter is inadvertently omitted in the implementation of QStandardItemModel.

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

            @nst0022 said in model.index() returns wrong class:

            I guess the third parameter is inadvertently omitted in the implementation of QStandardItemModel.

            Let's at least start from the C++ documentation for Qt:

            QModelIndex QAbstractItemModel::index(int row, int column, const QModelIndex &parent = QModelIndex()) const
            This is marked [pure virtual], which means it has no implementation in QAbstractItemModel and must be overridden in inheritors.

            QModelIndex QStandardItemModel::index(int row, int column, const QModelIndex &parent = QModelIndex()) const
            This is marked [override virtual]. And documented:

            Reimplements: QAbstractItemModel::index(int row, int column, const QModelIndex &parent) const.

            QStandardItemModel does not offer any other definition for index().

            Now I'm getting lost. You originally were asking about index() method. You now show an error message

                item             = modelIndex.model().item(0, 0, modelIndexParent)
            TypeError: PySide2.QtGui.QStandardItemModel.item(): too many arguments
            

            That is item() method.

            QAbstractItemModel does not have any item() method to override, and QStandardItemModel has just item(int row, int column = 0) which is indeed 2 not 3 arguments.

            Before I look any further, could you clarify which method you are finding at fault?

            BTW, if you are wanting a tree model from a QStandardItemModel then https://doc.qt.io/qt-5/qstandarditemmodel.html#details gives some sample code. Note it includes:

            Since a QAbstractItemView provides QModelIndex-based signals and functions, you need a way to obtain the QStandardItem that corresponds to a given QModelIndex, and vice versa. itemFromIndex() and indexFromItem() provide this mapping.
            QStandardItem *item = myStandardItemModel->itemFromIndex(index);

            nst0022N 1 Reply Last reply
            2
            • JonBJ JonB

              @nst0022 said in model.index() returns wrong class:

              I guess the third parameter is inadvertently omitted in the implementation of QStandardItemModel.

              Let's at least start from the C++ documentation for Qt:

              QModelIndex QAbstractItemModel::index(int row, int column, const QModelIndex &parent = QModelIndex()) const
              This is marked [pure virtual], which means it has no implementation in QAbstractItemModel and must be overridden in inheritors.

              QModelIndex QStandardItemModel::index(int row, int column, const QModelIndex &parent = QModelIndex()) const
              This is marked [override virtual]. And documented:

              Reimplements: QAbstractItemModel::index(int row, int column, const QModelIndex &parent) const.

              QStandardItemModel does not offer any other definition for index().

              Now I'm getting lost. You originally were asking about index() method. You now show an error message

                  item             = modelIndex.model().item(0, 0, modelIndexParent)
              TypeError: PySide2.QtGui.QStandardItemModel.item(): too many arguments
              

              That is item() method.

              QAbstractItemModel does not have any item() method to override, and QStandardItemModel has just item(int row, int column = 0) which is indeed 2 not 3 arguments.

              Before I look any further, could you clarify which method you are finding at fault?

              BTW, if you are wanting a tree model from a QStandardItemModel then https://doc.qt.io/qt-5/qstandarditemmodel.html#details gives some sample code. Note it includes:

              Since a QAbstractItemView provides QModelIndex-based signals and functions, you need a way to obtain the QStandardItem that corresponds to a given QModelIndex, and vice versa. itemFromIndex() and indexFromItem() provide this mapping.
              QStandardItem *item = myStandardItemModel->itemFromIndex(index);

              nst0022N Offline
              nst0022N Offline
              nst0022
              wrote on last edited by
              #5

              @JonB You are right, I confused item() and index()

              Now I am totally at lost.
              I have to thoroughly revisit the subject.

              JonBJ 1 Reply Last reply
              0
              • nst0022N nst0022

                @JonB You are right, I confused item() and index()

                Now I am totally at lost.
                I have to thoroughly revisit the subject.

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

                @nst0022
                Indeed :)

                I think that last "BTW" of mine might be what you are looking for in a hierarchical tree model: QStandardItem *QStandardItemModel::itemFromIndex(const QModelIndex &index) const.

                I am unsure how QStandardItem *QStandardItemModel::item(int row, int column = 0) const treats row in a hierarchical model, you would have to play with that to compare against itemFromIndex() which accepts a QModelIndex.

                1 Reply Last reply
                0
                • nst0022N Offline
                  nst0022N Offline
                  nst0022
                  wrote on last edited by
                  #7

                  Got it.

                  However, the result differs from the claimed problem in this thread:

                  I have a QTreeView.currenIndex() and wanted to retrieve an item from it, then obtain different data columns from this item, which led to the problem.

                  This is all nonsense.

                  With a QModelIndex, a column can easily be retrieved with:

                  myCurrentIndex.sibling(row, col)
                  

                  And that's it.

                  @JonB: I apologize for having made these waves and thank you for your patient assistance, which helped me find the solution :-).

                  JonBJ 1 Reply Last reply
                  0
                  • nst0022N nst0022

                    Got it.

                    However, the result differs from the claimed problem in this thread:

                    I have a QTreeView.currenIndex() and wanted to retrieve an item from it, then obtain different data columns from this item, which led to the problem.

                    This is all nonsense.

                    With a QModelIndex, a column can easily be retrieved with:

                    myCurrentIndex.sibling(row, col)
                    

                    And that's it.

                    @JonB: I apologize for having made these waves and thank you for your patient assistance, which helped me find the solution :-).

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

                    @nst0022
                    Yes, QModelIndex.sibling() is a convenient way to access another item from a QModelIndex. For same row but different column QModelIndex QModelIndex::siblingAtColumn(int column) const is even more convenient.

                    1 Reply Last reply
                    0
                    • nst0022N Offline
                      nst0022N Offline
                      nst0022
                      wrote on last edited by
                      #9

                      I have now figured out, why I had trouble with the item() and index() functions.

                      If you look-up code on the Internet, both C and Python examples exist, where a model has an index() function.

                      However, the Python documentation of QStandardItemModel does not mention index() in its function list, where the corresponding C documentation does (in Reimplemented Public Functions), but the function can be used in Python anyway.

                      I assume, that it does not make sense to report this kind of Python documentation errors, as long as the examples still contain C code.

                      JonBJ 1 Reply Last reply
                      0
                      • nst0022N nst0022

                        I have now figured out, why I had trouble with the item() and index() functions.

                        If you look-up code on the Internet, both C and Python examples exist, where a model has an index() function.

                        However, the Python documentation of QStandardItemModel does not mention index() in its function list, where the corresponding C documentation does (in Reimplemented Public Functions), but the function can be used in Python anyway.

                        I assume, that it does not make sense to report this kind of Python documentation errors, as long as the examples still contain C code.

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

                        @nst0022
                        When I first did Qt I was Python. That was PyQt5. PySide2 didn't exist yet, and that documentation you refer to is for PySide2. There isn't an equivalent for PyQt5. The PySide2 stuff largely holds.

                        So PyQt5 made you look up the C++ Qt documentation anyway. My advice would be you should combine that C++ look up with the PySide2. The PySide2 is mostly some kind of "copy" from the C++. It may have omissions. Anyway, there's my tip, use the C++ as well at least.

                        nst0022N 1 Reply Last reply
                        1
                        • JonBJ JonB

                          @nst0022
                          When I first did Qt I was Python. That was PyQt5. PySide2 didn't exist yet, and that documentation you refer to is for PySide2. There isn't an equivalent for PyQt5. The PySide2 stuff largely holds.

                          So PyQt5 made you look up the C++ Qt documentation anyway. My advice would be you should combine that C++ look up with the PySide2. The PySide2 is mostly some kind of "copy" from the C++. It may have omissions. Anyway, there's my tip, use the C++ as well at least.

                          nst0022N Offline
                          nst0022N Offline
                          nst0022
                          wrote on last edited by
                          #11

                          @JonB Aha, good to know.

                          One should never be too picky with documentation :-).

                          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