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 erroneously fetches all items with fetchMore()

QTreeView erroneously fetches all items with fetchMore()

Scheduled Pinned Locked Moved Unsolved General and Desktop
qtreeviewcanfetchmorefetchmore
9 Posts 3 Posters 3.1k 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.
  • A Offline
    A Offline
    atomblender
    wrote on last edited by atomblender
    #1

    Hi, I'm developing a program which on user's request fetches some data from Internet, stores it in a QAbstractTableModel derived model and shows it in QTreeView.

    My model reimplements canFetchMore() and fetchMore() functions so additional data is only downloaded when the user scrolls to the end of the list. Because I don't have the data at hand when it's needed (it must be downloaded first), I can't just add new data in fetchMore(). So instead I just make a request in fetchMore() and when the data arrives it is added to the model.

    And here is the problem: when my model is used by QTreeView, the view calls fetchMore() automatically until canFetchMore() returns false (so all data items were fetched). This is a different behavior from QListView and QTableView which both correctly call fetchMore() only once and when later the data arrives they stop calling fetchMore() unless the user scrolls to the end of the list.

    I've prepared a simplified example. There is a base model class and two derived models which reimplement fetchMore(): first model adds items synchronously in fetchMore() and the other one asynchronously with QTimer::singleshot() invoked in fetchMore(). QTreeView works correctly with the synchronous model but not with the asynchronous one.

    Model base class:

    class ModelBase : public QAbstractListModel
    {
    public:
    // {...}
       void createMoreItems();
    protected:
       bool moreItemsAvailable; // true if items.size() <  maxItems
    private:
        std::vector<QString> items;
        const int maxItems = 1000; // don't fetch more then this
        const int itemsPerRequest = 50;
    };
    
    bool ModelBase::canFetchMore(const QModelIndex &parent) const
    {
        return moreItemsAvailable;
    }
    
    void ModelBase::createMoreItems()
    {
        if (!moreItemsAvailable)
            return;
    
        QStringList newItems;
        for (int i = 0; i < itemsPerRequest; ++i)
            newItems.push_back(QString("Item ") + QString::number(items.size() + i));
    
        beginInsertRows(QModelIndex(), items.size(), items.size() + newItems.size() - 1);
    
        items.insert(items.end(), newItems.begin(), newItems.end());
        moreItemsAvailable = (items.size() <  maxItems ? true : false);
    
        endInsertRows();
    }
    

    Synchronous model adds items directly in fetchMore():

    void SynchronousModel::fetchMore(const QModelIndex &parent)
    {
        createMoreItems();
    }
    

    Asynchronous model adds items asynchronously:

    void AsynchronousModel::fetchMore(const QModelIndex &parent)
    {
        QTimer::singleShot(0, this, &ModelBase::createMoreItems);
    }
    

    I also created a simple app that shows the problem: synchronous model works correctly with all views (QListView, QTableView, QTreeView) but asynchronous model doesn't work correctly with QTreeView.

    Screenshot: https://bugreports.qt.io/secure/attachment/71496/treeviewtest.png

    The project archive: https://bugreports.qt.io/secure/attachment/71497/treeviewtest.zip

    So I wonder if I don't understand something about Model/View in Qt or it's a Qt bug?

    Also, I use QTreeView instead of QTableView with my QAbstractTableModel derived class because I want that mouse hover highlights entire row instead of a single cell which is probably not possible in QTableView without some workarounds.0_1523484146080_treeviewtest.png

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

      This looks like https://bugreports.qt.io/browse/QTBUG-18075 - at least the backtrace looks like the description there

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

      A 1 Reply Last reply
      4
      • Christian EhrlicherC Christian Ehrlicher

        This looks like https://bugreports.qt.io/browse/QTBUG-18075 - at least the backtrace looks like the description there

        A Offline
        A Offline
        atomblender
        wrote on last edited by
        #3

        @Christian-Ehrlicher: Thanks for reply. I've also tried to find bugs related to fetchMore():
        https://bugreports.qt.io/browse/QTBUG-18075?jql=text ~ "fetchmore"
        Without success, however. I'm thinking now about reporting a bug but I'm worried that it's a bug in my own code.

        VRoninV 1 Reply Last reply
        0
        • A atomblender

          @Christian-Ehrlicher: Thanks for reply. I've also tried to find bugs related to fetchMore():
          https://bugreports.qt.io/browse/QTBUG-18075?jql=text ~ "fetchmore"
          Without success, however. I'm thinking now about reporting a bug but I'm worried that it's a bug in my own code.

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

          @atomblender said in QTreeView erroneously fetches all items with fetchMore():

          I'm worried that it's a bug in my own code.

          Yes and no. I can see how you want it to work but the problem is you are telling lies to your view in the async way.

          You return true from canFetchMore so the view fetches and lays out the new data but you are delaying when that data is made available so the view thinks it still needs to lay it out and so repeats the process. This ends when canFetchMore returns false so the view gives up. At this point the model processes all the data fetching and signals the view to repaint itself

          "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

          A 1 Reply Last reply
          4
          • VRoninV VRonin

            @atomblender said in QTreeView erroneously fetches all items with fetchMore():

            I'm worried that it's a bug in my own code.

            Yes and no. I can see how you want it to work but the problem is you are telling lies to your view in the async way.

            You return true from canFetchMore so the view fetches and lays out the new data but you are delaying when that data is made available so the view thinks it still needs to lay it out and so repeats the process. This ends when canFetchMore returns false so the view gives up. At this point the model processes all the data fetching and signals the view to repaint itself

            A Offline
            A Offline
            atomblender
            wrote on last edited by atomblender
            #5

            @VRonin: Thanks for your reply. What is confusing is that the documentation for canFetchMore(), fetchMore() and Model/View Programming is not clear whether it is mandatory to insert new items synchronously and that QListView and QTableView work correctly with asynchronous item fetching. This inconsistency in behavior leads me to believe that it might be a bug in QTreeView. Another possibility is that there is something special about QTreeView.

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

              QTreeView, differently from the others need to query individual items to lay out itself (basically it needs to know if an item in the first column has children or not).

              I'm not saying this behaviour is totally intended and ideal, what I'm saying is that your use case is in a grey area of who's to blame and I wouldn't be surprised if your bug report ends up with an "invalid" sticker on it (i'm not involved in Qt development at all so I might be epically wrong)

              "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
              3
              • A Offline
                A Offline
                atomblender
                wrote on last edited by atomblender
                #7

                I've reported a bug: 67693

                If it's a real bug then the issue will hopefully be fixed. If it's a QTreeview's limitation or the bug won't be fixed than I will have to find a workaround. At the very least the matter will be clarified.

                VRoninV 1 Reply Last reply
                0
                • A atomblender

                  I've reported a bug: 67693

                  If it's a real bug then the issue will hopefully be fixed. If it's a QTreeview's limitation or the bug won't be fixed than I will have to find a workaround. At the very least the matter will be clarified.

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

                  @atomblender Put the affected version as the latest one or you might get ignored

                  "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

                  A 1 Reply Last reply
                  1
                  • VRoninV VRonin

                    @atomblender Put the affected version as the latest one or you might get ignored

                    A Offline
                    A Offline
                    atomblender
                    wrote on last edited by atomblender
                    #9

                    @VRonin: Ok, updated to 5.10.1

                    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