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. Subclassing QModelIndex - private constructor?
QtWS25 Last Chance

Subclassing QModelIndex - private constructor?

Scheduled Pinned Locked Moved Solved General and Desktop
qmodelindex
20 Posts 4 Posters 2.9k 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
    dheerendra
    Qt Champions 2022
    wrote on 24 Nov 2018, 16:57 last edited by
    #4

    Y do u need extra functions in Qmodelindex ? It is transient. May be we can do same thing somewhere else ?

    Dheerendra
    @Community Service
    Certified Qt Specialist
    http://www.pthinks.com

    D 1 Reply Last reply 24 Nov 2018, 16:59
    0
    • D dheerendra
      24 Nov 2018, 16:57

      Y do u need extra functions in Qmodelindex ? It is transient. May be we can do same thing somewhere else ?

      D Offline
      D Offline
      Dariusz
      wrote on 24 Nov 2018, 16:59 last edited by Dariusz
      #5

      @dheerendra said in Subclassing QModelIndex - private constructor?:

      Y do u need extra functions in Qmodelindex ? It is transient. May be we can do same thing somewhere else ?

      Well I've been trying to get my abstract model system to work with sharedPtrs but I'm getting some bad results when I try to retrieve the item back from the QModelIndex. I was hoping I can subclass it and just add the needed 1 function&member to solve the issue.

      Here is more on the subject > https://forum.qt.io/topic/96862/qabstractitemmodel-shared_ptr-issue-itemfromindex/6

      Say if I wish to create QModelIndex(0,0,sharedPtr) I need to pass sharedPtr as & so &sharedPtr, but that is a RAW pointer to shared_ptr in that function, which means that once function ends, that pointer gets deleted and my raw pointer now points in to emtiness, which then when I try to do statitc_cast end up being being bad object and I get lots of null/bad memory results.

      I was hoping to give Qt QmodelIndex a sharedPtr.get() for QT to be happy, but at the same time keep a sharedPtr as a member in my inherited class so that at later date when I do itemFromIndex() I can retrieve the correct shared_ptr/data.

      1 Reply Last reply
      0
      • C Offline
        C Offline
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote on 24 Nov 2018, 17:28 last edited by
        #6

        Don't use shared pointers there and you're fine. Or just store an index in the void* which you can map to your desired shared ptr

        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
          Dariusz
          wrote on 24 Nov 2018, 17:30 last edited by Dariusz
          #7

          I need to use shared_ptrs as we wish to expose the tree hierarchy to python via pybind11 which requires shared_ptrs.

          Storing an index in the void* sounds interesting, essentially creating another "temporary ModelIndex alike object" that can be used to retrieve my data structure easier. The only problem I have with that is that, when QmodelIndex is deleted, how do I delete the object that the QmodelIdnex had stored in its void* ? Does QmodelIndex provide any function call on delete or something like that?

          Hmm the more I think about it, perhaps I can store that item in treeItem itself mhmmm but that also poses some dangers, Esentially shared_ptr item storing shared_ptr to itself within itself as member...

          1 Reply Last reply
          0
          • C Offline
            C Offline
            Christian Ehrlicher
            Lifetime Qt Champion
            wrote on 24 Nov 2018, 17:54 last edited by
            #8

            @Dariusz said in Subclassing QModelIndex - private constructor?:

            when QmodelIndex is deleted

            A QModelIndex does not store anything so there can't be deleted anything when a QModelIndex is deleted. A QModelIndex just holds information about a cell and how to get to the underlying data.

            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 24 Nov 2018, 17:59
            2
            • C Christian Ehrlicher
              24 Nov 2018, 17:54

              @Dariusz said in Subclassing QModelIndex - private constructor?:

              when QmodelIndex is deleted

              A QModelIndex does not store anything so there can't be deleted anything when a QModelIndex is deleted. A QModelIndex just holds information about a cell and how to get to the underlying data.

              D Offline
              D Offline
              Dariusz
              wrote on 24 Nov 2018, 17:59 last edited by Dariusz
              #9

              @Christian-Ehrlicher Given that you store underlying data in vector as std::shared_ptr<treeItem>, how would you pass that to QModelIndex&retrieve it later so that shared_ptr count gets properly managed and you can work with it?
              ItemFromIndex() etc?

              Currently I'm using createIndex(row,col,sharedPtr.get()), but that breaks in many cases for some weird reasons I cant track down :- (

              1 Reply Last reply
              0
              • C Offline
                C Offline
                Christian Ehrlicher
                Lifetime Qt Champion
                wrote on 24 Nov 2018, 19:15 last edited by
                #10

                Since the QModelIndex does not store any data but just points to the data it a plain pointer is ok.

                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 24 Nov 2018, 19:22
                0
                • C Christian Ehrlicher
                  24 Nov 2018, 19:15

                  Since the QModelIndex does not store any data but just points to the data it a plain pointer is ok.

                  D Offline
                  D Offline
                  Dariusz
                  wrote on 24 Nov 2018, 19:22 last edited by
                  #11

                  @Christian-Ehrlicher said in Subclassing QModelIndex - private constructor?:

                  Since the QModelIndex does not store any data but just points to the data it a plain pointer is ok.

                  Well can it store shared_ptr ?

                  K C 2 Replies Last reply 25 Nov 2018, 04:22
                  0
                  • D Dariusz
                    24 Nov 2018, 19:22

                    @Christian-Ehrlicher said in Subclassing QModelIndex - private constructor?:

                    Since the QModelIndex does not store any data but just points to the data it a plain pointer is ok.

                    Well can it store shared_ptr ?

                    K Offline
                    K Offline
                    kshegunov
                    Moderators
                    wrote on 25 Nov 2018, 04:22 last edited by
                    #12

                    @Dariusz said in Subclassing QModelIndex - private constructor?:

                    Well can it store shared_ptr ?

                    No.

                    Read and abide by the Qt Code of Conduct

                    1 Reply Last reply
                    0
                    • D Dariusz
                      24 Nov 2018, 19:22

                      @Christian-Ehrlicher said in Subclassing QModelIndex - private constructor?:

                      Since the QModelIndex does not store any data but just points to the data it a plain pointer is ok.

                      Well can it store shared_ptr ?

                      C Offline
                      C Offline
                      Christian Ehrlicher
                      Lifetime Qt Champion
                      wrote on 25 Nov 2018, 07:13 last edited by
                      #13

                      @Dariusz said in Subclassing QModelIndex - private constructor?:

                      Well can it store shared_ptr ?

                      Once again: A QModelIndex does not store the data so even it you could store a pointer there it would be the wrong way.

                      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 25 Nov 2018, 09:06
                      0
                      • C Christian Ehrlicher
                        25 Nov 2018, 07:13

                        @Dariusz said in Subclassing QModelIndex - private constructor?:

                        Well can it store shared_ptr ?

                        Once again: A QModelIndex does not store the data so even it you could store a pointer there it would be the wrong way.

                        D Offline
                        D Offline
                        Dariusz
                        wrote on 25 Nov 2018, 09:06 last edited by Dariusz
                        #14

                        @Christian-Ehrlicher It stores a pointer to data node, In Qt native case its QStandardItem*. I'm trying to store the same thing but my objects are done via shared_ptr instead of raw pointers.

                        So again, I kinda need to extend the class or else a way to pass shared_ptr to the void*adata parameter/quintptr.

                        @kshegunov Is that not good enough reason to expose the constructor to allow users to subclass the QModelIdnex class to allow for a work around to store it?

                        K 1 Reply Last reply 25 Nov 2018, 09:48
                        0
                        • D Dariusz
                          25 Nov 2018, 09:06

                          @Christian-Ehrlicher It stores a pointer to data node, In Qt native case its QStandardItem*. I'm trying to store the same thing but my objects are done via shared_ptr instead of raw pointers.

                          So again, I kinda need to extend the class or else a way to pass shared_ptr to the void*adata parameter/quintptr.

                          @kshegunov Is that not good enough reason to expose the constructor to allow users to subclass the QModelIdnex class to allow for a work around to store it?

                          K Offline
                          K Offline
                          kshegunov
                          Moderators
                          wrote on 25 Nov 2018, 09:48 last edited by kshegunov
                          #15

                          @Dariusz said in Subclassing QModelIndex - private constructor?:

                          @Christian-Ehrlicher It stores a pointer to data node

                          First of all, it stores an opaque pointer, which can be any pointer.

                          I'm trying to store the same thing but my objects are done via shared_ptr instead of raw pointers.

                          Secondly, this is not a pointer! This is an object that aggregates a pointer. An object, no matter what it contains, isn't a pointer itself.

                          So again, I kinda need to extend the class or else a way to pass shared_ptr to the void*adata parameter/quintptr.

                          You can't and you will not. If you want to reference a list of shared pointers, put them in a vector, and store the index of the element inside the model index. When you need to get the shared pointer, take the index of the element from the model index and get the shared pointer from the vector.

                          @kshegunov Is that not good enough reason to expose the constructor to allow users to subclass the QModelIdnex class to allow for a work around to store it?

                          No. It was already said that a model index does not and will not store data directly. It references data that's someplace else, that is - somewhere you've put it. It has 2 constructors to facilitate that:

                          1. one that takes a void * - a generic pointer to something
                          2. one that takes an integer - a generic index to something

                          It is your responsibility to keep and manage the data.

                          Read and abide by the Qt Code of Conduct

                          D 1 Reply Last reply 25 Nov 2018, 13:25
                          2
                          • K kshegunov
                            25 Nov 2018, 09:48

                            @Dariusz said in Subclassing QModelIndex - private constructor?:

                            @Christian-Ehrlicher It stores a pointer to data node

                            First of all, it stores an opaque pointer, which can be any pointer.

                            I'm trying to store the same thing but my objects are done via shared_ptr instead of raw pointers.

                            Secondly, this is not a pointer! This is an object that aggregates a pointer. An object, no matter what it contains, isn't a pointer itself.

                            So again, I kinda need to extend the class or else a way to pass shared_ptr to the void*adata parameter/quintptr.

                            You can't and you will not. If you want to reference a list of shared pointers, put them in a vector, and store the index of the element inside the model index. When you need to get the shared pointer, take the index of the element from the model index and get the shared pointer from the vector.

                            @kshegunov Is that not good enough reason to expose the constructor to allow users to subclass the QModelIdnex class to allow for a work around to store it?

                            No. It was already said that a model index does not and will not store data directly. It references data that's someplace else, that is - somewhere you've put it. It has 2 constructors to facilitate that:

                            1. one that takes a void * - a generic pointer to something
                            2. one that takes an integer - a generic index to something

                            It is your responsibility to keep and manage the data.

                            D Offline
                            D Offline
                            Dariusz
                            wrote on 25 Nov 2018, 13:25 last edited by Dariusz
                            #16

                            @kshegunov said in Subclassing QModelIndex - private constructor?:

                            @Dariusz said in Subclassing QModelIndex - private constructor?:

                            @Christian-Ehrlicher It stores a pointer to data node

                            First of all, it stores an opaque pointer, which can be any pointer.

                            Except it cant store shared_ptr ?

                            I'm trying to store the same thing but my objects are done via shared_ptr instead of raw pointers.

                            Secondly, this is not a pointer! This is an object that aggregates a pointer. An object, no matter what it contains, isn't a pointer itself.

                            Hmm yeap true. Still it has "pointer" written all over it and as far as I can tell its raw 2.0 pointer. Even Qt has its own implementation of QSharedPtr as far as I remember. Perhaps they all should change the naming to call it shared_wrapper/smart_wrapper ? / anyway waving off the topic here.

                            So again, I kinda need to extend the class or else a way to pass shared_ptr to the void*adata parameter/quintptr.

                            You can't and you will not. If you want to reference a list of shared pointers, put them in a vector, and store the index of the element inside the model index. When you need to get the shared pointer, take the index of the element from the model index and get the shared pointer from the vector.

                            Not sure how much performance that will yeld, I'm looking at milions of objects, if I need to keep making/deleting vectors I will lose cycles on just handling the massive vector list. Not to mention if I want to delete 500k objects, then I need to filter over the vector to clear objects there too... with shared_ptr/QModelIndex, the second QModelIndex dies and if its the last index then the object would get deleted too.

                            @kshegunov Is that not good enough reason to expose the constructor to allow users to subclass the QModelIdnex class to allow for a work around to store it?

                            No. It was already said that a model index does not and will not store data directly. It references data that's someplace else, that is - somewhere you've put it. It has 2 constructors to facilitate that:

                            1. one that takes a void * - a generic pointer to something
                            2. one that takes an integer - a generic index to something

                            It is your responsibility to keep and manage the data.

                            It does not store data no, yes that's correct. But it stored a pointer to the data.
                            Right now QStandardModelItem/QStandardItem are based on *Raw pointers. So it's all nice. But if a user(me) wants to use QAbstractItemModel & customItem based on shared_ptr<> then I have no way of using QModelIndex to store/retrieve the internalPointer in a correct format that won't break shared_ptr<>.

                            As far as I can tell shared_ptr are being pushed out there to replace raw ptrs so that memory leaks are easier to fix and memory is managed better. Why is it so hard to either expose constructor for qmodelIndex or add a way for it to work with shared_ptr? All its need is std::shared_ptr<void>> - but that needs more hassle, or just expose the constructor from private to public? :/

                            Sorry if I'm being a little "Stubborn" but we have the tools to replace qabstractmodel/treeView/item etc. But nothing for ModelIndex...

                            K 1 Reply Last reply 25 Nov 2018, 17:27
                            0
                            • C Offline
                              C Offline
                              Christian Ehrlicher
                              Lifetime Qt Champion
                              wrote on 25 Nov 2018, 16:46 last edited by Christian Ehrlicher
                              #17

                              @Dariusz said in Subclassing QModelIndex - private constructor?:

                              But it stored a pointer to the data.

                              No, it does not store anything, you're wrong. A QModelIndex has no ownership on something. A shared_ptr is exactly the opposite - it is a shared ownership to a data structure/object.

                              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
                              • D Dariusz
                                25 Nov 2018, 13:25

                                @kshegunov said in Subclassing QModelIndex - private constructor?:

                                @Dariusz said in Subclassing QModelIndex - private constructor?:

                                @Christian-Ehrlicher It stores a pointer to data node

                                First of all, it stores an opaque pointer, which can be any pointer.

                                Except it cant store shared_ptr ?

                                I'm trying to store the same thing but my objects are done via shared_ptr instead of raw pointers.

                                Secondly, this is not a pointer! This is an object that aggregates a pointer. An object, no matter what it contains, isn't a pointer itself.

                                Hmm yeap true. Still it has "pointer" written all over it and as far as I can tell its raw 2.0 pointer. Even Qt has its own implementation of QSharedPtr as far as I remember. Perhaps they all should change the naming to call it shared_wrapper/smart_wrapper ? / anyway waving off the topic here.

                                So again, I kinda need to extend the class or else a way to pass shared_ptr to the void*adata parameter/quintptr.

                                You can't and you will not. If you want to reference a list of shared pointers, put them in a vector, and store the index of the element inside the model index. When you need to get the shared pointer, take the index of the element from the model index and get the shared pointer from the vector.

                                Not sure how much performance that will yeld, I'm looking at milions of objects, if I need to keep making/deleting vectors I will lose cycles on just handling the massive vector list. Not to mention if I want to delete 500k objects, then I need to filter over the vector to clear objects there too... with shared_ptr/QModelIndex, the second QModelIndex dies and if its the last index then the object would get deleted too.

                                @kshegunov Is that not good enough reason to expose the constructor to allow users to subclass the QModelIdnex class to allow for a work around to store it?

                                No. It was already said that a model index does not and will not store data directly. It references data that's someplace else, that is - somewhere you've put it. It has 2 constructors to facilitate that:

                                1. one that takes a void * - a generic pointer to something
                                2. one that takes an integer - a generic index to something

                                It is your responsibility to keep and manage the data.

                                It does not store data no, yes that's correct. But it stored a pointer to the data.
                                Right now QStandardModelItem/QStandardItem are based on *Raw pointers. So it's all nice. But if a user(me) wants to use QAbstractItemModel & customItem based on shared_ptr<> then I have no way of using QModelIndex to store/retrieve the internalPointer in a correct format that won't break shared_ptr<>.

                                As far as I can tell shared_ptr are being pushed out there to replace raw ptrs so that memory leaks are easier to fix and memory is managed better. Why is it so hard to either expose constructor for qmodelIndex or add a way for it to work with shared_ptr? All its need is std::shared_ptr<void>> - but that needs more hassle, or just expose the constructor from private to public? :/

                                Sorry if I'm being a little "Stubborn" but we have the tools to replace qabstractmodel/treeView/item etc. But nothing for ModelIndex...

                                K Offline
                                K Offline
                                kshegunov
                                Moderators
                                wrote on 25 Nov 2018, 17:27 last edited by
                                #18

                                @Dariusz said in Subclassing QModelIndex - private constructor?:

                                Except it cant store shared_ptr ?

                                Because that's an object, not a pointer. It has additional data it holds, beside the pointer to your object. In fact it holds at the very least an integer and one pointer in addition to the original pointer to the object.

                                Hmm yeap true. Still it has "pointer" written all over it and as far as I can tell its raw 2.0 pointer.

                                No it is not. It's a rather expensive mechanism that allows to share ownership to a pointer. And just to be clear, it does not share ownership to the data a pointer references, only to the pointer.

                                Perhaps they all should change the naming to call it shared_wrapper/smart_wrapper ?

                                Take that with the standards committee. Sharing of pointers is quite the rare case anyway.

                                Not sure how much performance that will yeld, I'm looking at milions of objects, if I need to keep making/deleting vectors I will lose cycles on just handling the massive vector list.

                                Yeah, and atomic reference counting over an external counter is absolutely free, right?

                                Not to mention if I want to delete 500k objects, then I need to filter over the vector to clear objects there too... with shared_ptr/QModelIndex, the second QModelIndex dies and if its the last index then the object would get deleted too.

                                If you need to allocate/delete half a million objects the heap manager will eat up your CPU time like it never existed anyway. new/delete ain't free of charge.

                                But it stored a pointer to the data.

                                You can store a pointer to the data if you wish. QModelIndex will not take ownership, however, so even semantically giving it a shared pointer is wrong. You're trying to force QModelIndex to be owner of some pointer you share with other parts of your program. You're fighting with the model-view framework. I repeat, it is wrong and will not work.

                                Right now QStandardModelItem/QStandardItem are based on *Raw pointers. So it's all nice. But if a user(me) wants to use QAbstractItemModel & customItem based on shared_ptr<> then I have no way of using QModelIndex to store/retrieve the internalPointer in a correct format that won't break shared_ptr<>.

                                Because you made a wrong design choice. You'll just have to live with it. I understand what you want to do, it's not going to happen.

                                As far as I can tell shared_ptr are being pushed out there to replace *raw ptrs so that memory leaks are easier to fix and memory is managed better.

                                You are wrong. If that were true you'd see everything in Qt passed through a shared pointer. Have you? Of course not, because external reference counting is not "memory management" by itself. Proper memory management requires discipline to declare clearly what object owns what memory, which many people lack or simply refuse to acknowledge. The std::shared_ptr and it's Qt conterpart QSharedPointer are good for one thing and one thing alone - objects that manage their own lifetime, i.e. they are not owned by any other object, thus the reference to them must be shared.

                                Why is it so hard to either expose constructor for qmodelIndex or add a way for it to work with shared_ptr?

                                Many reasons. One of them is it breaks binary compatibility. Another is that QModelIndex has to be a template (or an abstract) class to be able to do it, which isn't happening because it can't work with the rest of the model/view. And last, but not least, it's neither necessary, nor is it a correct approach.

                                All its need is std::shared_ptr<void*>> - but that needs more hassle, or just expose the constructor from private to public? :/

                                QModelIndex isn't made to be derived, that's why it has a private constructor.

                                Read and abide by the Qt Code of Conduct

                                1 Reply Last reply
                                3
                                • C Offline
                                  C Offline
                                  Christian Ehrlicher
                                  Lifetime Qt Champion
                                  wrote on 25 Nov 2018, 17:35 last edited by
                                  #19

                                  @kshegunov said in Subclassing QModelIndex - private constructor?:

                                  If you need to allocate/delete half a million objects the heap manager will eat up your CPU time like it never existed anyway

                                  And the whole ref-counting stuff will eat the last cycles when there are some left... :)

                                  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
                                    Dariusz
                                    wrote on 25 Nov 2018, 17:36 last edited by
                                    #20

                                    Hmmmmmmmm Ok. Time to rethink my live decisions :- )

                                    Thanks so much for info & putting up with my whining.

                                    Thanks every one! :- )

                                    Regards
                                    Dariusz

                                    1 Reply Last reply
                                    0

                                    13/20

                                    25 Nov 2018, 07:13

                                    • Login

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