Results 1 to 5 of 5

Thread: How to indicate that hasChildren() has changed when using lazy population?

  1. #1
    Join Date
    Nov 2009
    Posts
    129
    Thanks
    4
    Thanked 29 Times in 29 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default How to indicate that hasChildren() has changed when using lazy population?

    I have a subclass of QAbstractItemModel which uses lazy population. Generally I know whether any given item has children before it is actually populated, but sometimes this changes even though the item is not yet populated.

    As long as a parent item is populated, I can just use QAbstractItemModel::beginInsertRows()/QAbstractItemModel::endInsertRows() or QAbstractItemModel::beginRemoveRows()/QAbstractItemModel::endRemoveRows() and, with proper adjustments in the various virtual functions, everything works fine. But when the parent item is not yet populated — QAbstractItemModel::canFetchMore() and QAbstractItemModel::hasChildren return the same value, either true or false, and QAbstractItemModel::rowCount() returns 0 — reversing the return values of QAbstractItemModel::canFetchMore() and QAbstractItemModel::hasChildren() doesn’t add or remove the expansion icon in a connected QTreeView without doing something else (which makes sense, since nothing has happened in the model that would send a signal to tell the view to call QAbstractItemModel::hasChildren() again for the item in question).

    What do I do in a QAbstractItemModel subclass to tell the connected views that they need to recheck the value of QAbstractItemModel::hasChildren() for a particular item, even though no children have been added or removed, since it is not yet populated?

  2. #2
    Join Date
    Jan 2006
    Location
    Belgium
    Posts
    1,938
    Thanked 268 Times in 268 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Wiki edits
    20

    Default Re: How to indicate that hasChildren() has changed when using lazy population?

    You can of course emit your own signals when you insert or remove items in your model.

    But I'm not really sure I understand your problem. If you do not have any childitems for a particular parent item, then hasChildren() will always return false. Do you want to have it return true if there are no children?

  3. #3
    Join Date
    Nov 2009
    Posts
    129
    Thanks
    4
    Thanked 29 Times in 29 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: How to indicate that hasChildren() has changed when using lazy population?

    Quote Originally Posted by tbscope View Post
    But I'm not really sure I understand your problem. If you do not have any childitems for a particular parent item, then hasChildren() will always return false. Do you want to have it return true if there are no children?
    Yes; in fact overriding QAbstractItemModel::hasChildren() to return true even though QAbstractItemModel::rowCount() returns 0 is exactly what one does to implement lazy population. (The documentation is less than clear on this, but experiment showed me that QAbstractItemModel::rowCount() must return 0 until the rows are actually inserted, following the call in QAbstractItemModel::fetchMore() to QAbstractItemModel::beginInsertRows() — which does itself call QAbstractItemModel::rowCount() and must see 0.)

    This all works as it should. The problem I can’t seem to resolve is what to do when the status of an unpopulated parent changes such that it no longer has children; or when the status of an item that previously did not have children changes such that it does, but information about the children should not be retrieved and added to the model until required. Debug statements suggest that QTreeView calls QAbstractModel::hasChildren() when it first shows an item, but nothing I can do in the model, short of removing the item and adding it back again, seems to make it call that function again and update the presence or absence of the expansion icon accordingly.

    In the user interface of the QTreeView, collapsing and expanding the item’s parent seems to do the trick; and once the item is populated (QAbstractItemModel::fetchMore() is called) there is no problem. The problem is in switching between childless and unpopulated states.

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: How to indicate that hasChildren() has changed when using lazy population?

    Quote Originally Posted by Coises View Post
    The problem I can’t seem to resolve is what to do when the status of an unpopulated parent changes such that it no longer has children;
    I would emit layoutChanged() or dataChanged() for the parent in question.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. The following user says thank you to wysota for this useful post:

    Coises (7th May 2010)

  6. #5
    Join Date
    Nov 2009
    Posts
    129
    Thanks
    4
    Thanked 29 Times in 29 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: How to indicate that hasChildren() has changed when using lazy population?

    Quote Originally Posted by wysota View Post
    I would emit layoutChanged() or dataChanged() for the parent in question.
    Thank you, Wysota! A single layoutChanged() after a batch of changes appears to work perfectly.

Similar Threads

  1. Delayed QAbstractItemModel population
    By BlackDemon in forum Qt Programming
    Replies: 0
    Last Post: 8th December 2009, 00:17
  2. QStandardItemModel Lazy Population
    By AaronMK in forum Qt Programming
    Replies: 0
    Last Post: 15th September 2009, 08:05
  3. Replies: 1
    Last Post: 9th August 2009, 19:51
  4. Replies: 4
    Last Post: 6th February 2009, 19:18
  5. Lazy population of QAbstractModel
    By bastien in forum Qt Programming
    Replies: 1
    Last Post: 16th January 2009, 20:25

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.