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. When is AbstractItemModel's data() method called ?
Forum Updated to NodeBB v4.3 + New Features

When is AbstractItemModel's data() method called ?

Scheduled Pinned Locked Moved General and Desktop
6 Posts 3 Posters 3.2k 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.
  • W Offline
    W Offline
    wejou
    wrote on last edited by
    #1

    Is there documentation for when AbstractItemModel's data() method is called ?

    It seems that my application has many unnecessary calls to AbstractItemModel::data(). I'm using AbstractTableModel and I understand that data() must be called multiple times for the various roles of an index. I would expect data() to be called when the table is initially drawn and when a modification is made to a cell. Also, I'm not manually redrawing the anywhere in code.

    I tried to get more details by having the rowCount() and columnCount() return 1 so I essentially have a table with only one cell. Next, I put a print statement inside data() and I could see it is being called for roles 6,7,9,10,1,0, and 8. The problem is that it does this four times so it's being called 28 times (7 roles * 4 times = 28) for only one cell in the table.

    Understanding the sequence of calls for the Model/View architecture is critical to my doing well on this project. Any documentation on the sequence of calls (i.e. when is data()/setData() etc. called) ? Any advice ? I can provide code if necessary.

    1 Reply Last reply
    0
    • Chris KawaC Offline
      Chris KawaC Offline
      Chris Kawa
      Lifetime Qt Champion
      wrote on last edited by
      #2

      The timing and order of data() calls is implementation detail of Qt and will likely change. It is not documented (officially).

      The recommendation is that data() should be implemented to be "as fast as possible". You shouldn't make any assumptions on when or how many times certain data role will be polled. Optimally a data() implementation should be a switch with bunch of returns and no (or almost no) calculations.
      If you need some heavy calculations for particular data roles you should consider caching it. You can take a look at QCache or QContiguousCache classes to see if they can help you out.

      1 Reply Last reply
      0
      • W Offline
        W Offline
        wejou
        wrote on last edited by
        #3

        Thank you Chris.

        I just noticed one thing. Here is main.cpp:

        @#include "CMainWindow.h"
        #include <QApplication>

        int main(int argc, char *argv[])
        {
        QApplication a(argc, argv);
        CMainWindow w;
        w.show();
        return a.exec();
        }@

        If I remove line 9, then data() gets called as many times as I would expect for the one table cell (i.e. getting each role ONCE upon launch). However, when I add the line, there are many more calls to data(). What is there about entering the main event loop (via exec()) that does this ?

        1 Reply Last reply
        0
        • Chris KawaC Offline
          Chris KawaC Offline
          Chris Kawa
          Lifetime Qt Champion
          wrote on last edited by
          #4

          As I said - that's an implementation detail so I can only speculate.

          I implemented an example just like you described:
          @#include <QApplication>
          #include <QAbstractItemModel>
          #include <QTableView>
          #include <QDebug>

          class Model : public QAbstractItemModel {
          public:
          Model(QObject* parent = nullptr) : QAbstractItemModel(parent) {}
          QModelIndex index(int row, int column, const QModelIndex&) const {
          return createIndex(row, column);
          }
          QModelIndex parent(const QModelIndex&) const {
          return QModelIndex();
          }
          int rowCount(const QModelIndex&) const {
          return 1;
          }
          int columnCount(const QModelIndex&) const {
          return 1;
          }
          QVariant data(const QModelIndex&, int role) const {
          qDebug() << role;
          return QVariant();
          }
          };

          int main(int argc, char *argv[])
          {
          QApplication a(argc, argv);
          QTableView w;
          w.setModel(new Model());
          w.show();
          return a.exec();
          }@
          The output is "6 7 9 10 1 0 8" and that's it. It's like that even if I hide and show the widget multiple times. When you look at the Qt::ItemDataRole definition these are all roles needed to draw a cell - a font, text, colors, decoration etc.

          So if you're getting these calls multiple times you're probably doing something else that forces the view to update. Check if you're not setting the model multiple times, resize the window(or just the widget), call setGeometry, resetModel, emit some signals that could trigger an update etc. I can't really help you more without seeing the whole context.

          1 Reply Last reply
          0
          • W Offline
            W Offline
            wejou
            wrote on last edited by
            #5

            Thank you Chris!

            I looked at my data() function and I was creating a copy of a map with 44000+ elements. This was the reason my interface lagged and not the many calls to data(). Your statement "data() should be implemented to be “as fast as possible” made me take a second look at my code. I still haven't figured out the reason for the many calls to data() (it's probably one of the things you listed), but I can at least continue with development.

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #6

              Hi,

              AFAIK, as soon as there is an update needed then data will be called. An update can be triggered for many reasons: moving the widget, moving another window over your widget, minimize/maximize and lots of other things that depends also on your model, if you called reset, layoutChanged etc.

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              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