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. QTreeView not showing first child added to parent
Forum Updated to NodeBB v4.3 + New Features

QTreeView not showing first child added to parent

Scheduled Pinned Locked Moved Solved General and Desktop
10 Posts 4 Posters 3.3k 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.
  • R Offline
    R Offline
    rickyviking
    wrote on last edited by rickyviking
    #1

    I have a QTreeView on top of a custom module.
    I allow the user to add a child item for a selected item in the model.
    Every time a child item is added to its parent, I invoke the begin/end pairs of method as documented here: http://doc.qt.io/qt-5/qabstractitemmodel.html#beginInsertRows
    After that, I also work on the view to focus on the added item, in particular:

    • obtain a QPersistentModelIndex corresponding to the parent
    • insert the child row
    • view->expand() on the parent item (through persistent index) to show its children
    • view->update() on the parent item
    • select the lastly added child

    This works almost all the time, EXCEPT when I add the first child to a parent element with no children.
    The item is correctly added to the model, but the view doesn't show it.
    Forcing a full expand/update on the view shows the item, but it not a good solution as modify the collapse state of all the tree items.

    It there something else/different I should do?
    Thanks

    P.S. When adding the first child to a model item, beginInsertRows() is invoked using beginInsertRow (parentQIndex, 0, 0) - I believe this is the correct call to do

    1 Reply Last reply
    0
    • VRoninV Offline
      VRoninV Offline
      VRonin
      wrote on last edited by
      #2

      Difficult to reply with no code. Can you post what you are doing?

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

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

      1 Reply Last reply
      0
      • R Offline
        R Offline
        rickyviking
        wrote on last edited by
        #3

        Here is an extract of the code which shows the issue I'm having when adding the first child to a parent element.
        Thank you

        // mView is a QTreeView
        // the model is a custom made model derived from QAbstractItemModel,
        // which adds the child elements correctly, see AddArrayEntry below
        
        // slot invoked when the  "add-child" button is pressed
        void AddChildSlot() 
        {
           // current selection from the view
           QModelIndex index = mView->selectionModel()->currentIndex();
           // helper class to implement the model
           PropertyTreeItem* item = static_cast<PropertyTreeItem*>(index.internalPointer());
        
           // selected element is the parent, add the new child at the end 
           if (/*parent item selected*/)
           {
              // save a persistent index corresponding to the array
              QPersistentModelIndex pmi(index);
        
              // see implementation below
              // the model adds the the item correctly
              mModel.AddArrayEntry(index);
        
              // does NOT work when adding the first child to the parent
              mView->expand(pmi);
              mView->update(pmi);
              // as a workaround I can use this, which messes up the view
              // mView->expandAll();
              // mView->update();
        
              // retrieve regular index from persistent one.
              QModelIndex normalIndex = pmi;
              // select added child
              mView->selectionModel()->setCurrentIndex(normalIndex.child(item->getNumChildren() - 1, 0), QItemSelectionModel::ClearAndSelect);
              mView->setFocus();
           }
        }
        
        
        void CustomModel::AddArrayEntry(const QModelIndex &index)
        {
           // grab internal pointer and prop
           PropertyTreeItem* item = static_cast<PropertyTreeItem*>(index.internalPointer());
        
           // get the internal array class
           <internal-array>* ap = item->AsArray();
        
           // compute index of the new row we're going to add
           int rowIndexToInsert = ap->Size();
        
           // notify row number about to change in the model
           beginInsertRows(index, rowIndexToInsert, rowIndexToInsert);
        
           // create a new element based on the prototype and the correspoding model tree item
           PropertyTreeItem* insertedItem = createTreeItem(/*params*/);
        
           // add the new item both on the internal array AND in the model wrapping it
           ap->Add(entry);
           item->addChild(insertedItem);
           
           // done inserting rows      
           endInsertRows();
        }
        
        1 Reply Last reply
        0
        • Maarouf Med MahdiM Offline
          Maarouf Med MahdiM Offline
          Maarouf Med Mahdi
          wrote on last edited by
          #4

          Hi, i read your problem description and your source code also , i hope that i can help you perfectly but i have something is ambiguous for me , and i need to understand them .

          • What do you mean by PropertyTreeItem class in your code , i think that a class dereaved from the abastractitemView or QStandarItem (did you mean the PropertyTreeItem * item the new item that you want to add ) ?
          • Just i wante to know how are you checked if the item is correctly added to the model (that my be wrong or is get the same result always ) ?

          I wante you to check befor this statement "PropertyTreeItem* item = static_cast<PropertyTreeItem*>(index.internalPointer());" if is doing the correct cast or no in the AddArrayEntry() method with debugging mode also rowIndexToInsert value when the item has no children .

          1 Reply Last reply
          0
          • VRoninV Offline
            VRoninV Offline
            VRonin
            wrote on last edited by
            #5

            Kind of guessing here but since you are not adding columns to the parent the view might just ignore the added rows. That would also explain why collapsing+expanding fixes it. try adding beginInsertColumns and endInsertColumns as well when the parent has no children

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

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

            R 1 Reply Last reply
            1
            • VRoninV VRonin

              Kind of guessing here but since you are not adding columns to the parent the view might just ignore the added rows. That would also explain why collapsing+expanding fixes it. try adding beginInsertColumns and endInsertColumns as well when the parent has no children

              R Offline
              R Offline
              rickyviking
              wrote on last edited by
              #6

              @VRonin said:

              Kind of guessing here but since you are not adding columns to the parent the view might just ignore the added rows. That would also explain why collapsing+expanding fixes it. try adding beginInsertColumns and endInsertColumns as well when the parent has no children

              Thanks @VRonin, I've tried your solution but still does not cover 100% of the cases.
              On the same line I've also tried mView->update() not only on the parent item, but also explicitly on all of its children: still working only sometimes, not always...

              @Maarouf-Med-Mahdi PropertyTreeItem is the internal used to build the model on, see: http://doc.qt.io/qt-5/qtwidgets-itemviews-simpletreemodel-example.html
              I'm sure the model is updated correctly because I've debugged it, and if I jump on another item and than relesect the one I've modified, the added child is shown correctly, which means that it's a problem of refreshing the view, not about the child item not added to the model.

              JonBJ VRoninV 2 Replies Last reply
              0
              • R rickyviking

                @VRonin said:

                Kind of guessing here but since you are not adding columns to the parent the view might just ignore the added rows. That would also explain why collapsing+expanding fixes it. try adding beginInsertColumns and endInsertColumns as well when the parent has no children

                Thanks @VRonin, I've tried your solution but still does not cover 100% of the cases.
                On the same line I've also tried mView->update() not only on the parent item, but also explicitly on all of its children: still working only sometimes, not always...

                @Maarouf-Med-Mahdi PropertyTreeItem is the internal used to build the model on, see: http://doc.qt.io/qt-5/qtwidgets-itemviews-simpletreemodel-example.html
                I'm sure the model is updated correctly because I've debugged it, and if I jump on another item and than relesect the one I've modified, the added child is shown correctly, which means that it's a problem of refreshing the view, not about the child item not added to the model.

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

                @rickyviking
                There seem to be a few questions about this type of behaviour.

                From one of them (https://forum.qt.io/topic/18024/solved-qtreeview-child-indicator-is-not-updated-after-inserting-children):

                • Are you using any kind of sort behaviour (inc. proxy) on the model/view?

                • Are your columnCount()s returning the same number on every single index in the view (possibly including the parent)?

                1 Reply Last reply
                3
                • R rickyviking

                  @VRonin said:

                  Kind of guessing here but since you are not adding columns to the parent the view might just ignore the added rows. That would also explain why collapsing+expanding fixes it. try adding beginInsertColumns and endInsertColumns as well when the parent has no children

                  Thanks @VRonin, I've tried your solution but still does not cover 100% of the cases.
                  On the same line I've also tried mView->update() not only on the parent item, but also explicitly on all of its children: still working only sometimes, not always...

                  @Maarouf-Med-Mahdi PropertyTreeItem is the internal used to build the model on, see: http://doc.qt.io/qt-5/qtwidgets-itemviews-simpletreemodel-example.html
                  I'm sure the model is updated correctly because I've debugged it, and if I jump on another item and than relesect the one I've modified, the added child is shown correctly, which means that it's a problem of refreshing the view, not about the child item not added to the model.

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

                  @rickyviking said in QTreeView not showing first child added to parent:

                  I'm sure the model is updated correctly because I've debugged it

                  When it comes to subclassing models you can never be sure, believe me.

                  @JonB 's points are 100% worth exploring but I'd also recommend running the model test alongside your program to make sure everything is implemented correctly

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

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

                  1 Reply Last reply
                  2
                  • R Offline
                    R Offline
                    rickyviking
                    wrote on last edited by
                    #9

                    Thanks @VRonin and @JonB for your suggestions.

                    I finally found the cause of my issue: the model I shared in the code snippet above is based on 2 columns.
                    Sometimes the method to add a new child row was invoked with an index referring to the right row, but to column 1 instead of 0, because the user might have selected that cell as last one.
                    This probably doesn't play well with begin/endInsertRows().
                    I have now checked that the column index for which I call begin/endInsertRows() is always 0, and after this change the view always updates correctly.

                    I confirm the model behaves correctly, but the model test is a nice tool anyway.

                    VRoninV 1 Reply Last reply
                    0
                    • R rickyviking

                      Thanks @VRonin and @JonB for your suggestions.

                      I finally found the cause of my issue: the model I shared in the code snippet above is based on 2 columns.
                      Sometimes the method to add a new child row was invoked with an index referring to the right row, but to column 1 instead of 0, because the user might have selected that cell as last one.
                      This probably doesn't play well with begin/endInsertRows().
                      I have now checked that the column index for which I call begin/endInsertRows() is always 0, and after this change the view always updates correctly.

                      I confirm the model behaves correctly, but the model test is a nice tool anyway.

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

                      @rickyviking said in QTreeView not showing first child added to parent:

                      This probably doesn't play well with begin/endInsertRows().

                      It does play well, however None of the views provided by Qt handle children of items in columns that are not the first one

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

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

                      1 Reply Last reply
                      0

                      • Login

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