Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How many kinds of inner signals are triggered in Qt when modify item in QStandardItemModel?
Qt 6.12 LTS is out! See what's new in the release blog

How many kinds of inner signals are triggered in Qt when modify item in QStandardItemModel?

Scheduled Pinned Locked Moved Solved General and Desktop
21 Posts 5 Posters 14.3k 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.
  • J.HilkJ J.Hilk

    @Lee908 since this, is like 14000 individual paint events all done via cpu, I'm not all to surprised by a visual delay in the update

    L Offline
    L Offline
    Lee908
    wrote on last edited by
    #11

    @J-Hilk said in How many kinds of inner signals are triggered in Qt when modify item in QStandardItemModel?:

    since this, is like 14000 individual paint events all done via cpu, I'm not all to surprised by a visual delay in the update

    @JonB 's demo has proved that it's not a problem for Qt to finish14000 individual paint events smoothly.

    1 Reply Last reply
    0
    • L Lee908

      @JonB

      What are you doing different from this?

      Your test is instantaneous is because you did setModel AFTER all items were created. Did you try it at beginning? Just take your example above, after your application 'tv' is displayed, user click a button to open file to load another 2000 rows into 'tv' (assumed there is a button). Guess if the loading work can be finished instantaneously or not?

      Create/Edit data in the model which is been set into a table view, it will trigger some inner signals. That's the KEY POINT of this case!

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

      @Lee908 said in How many kinds of inner signals are triggered in Qt when modify item in QStandardItemModel?:

      Did you try it at beginning?

      Yes, I had already done that:

      #include <QApplication>
      #include <QStandardItemModel>
      #include <QTableView>
      #include <QTimer>
      
      int main(int argc, char *argv[])
      {
          QApplication a(argc, argv);
          QTableView tv;
          QStandardItemModel im;
          im.setColumnCount(7);
          tv.setModel(&im);
          tv.show();
          QTimer::singleShot(0, [&im]() {
              for (int row = 0; row < 2000; row++)
              {
                  QList<QStandardItem *> items;
                  items.append(new QStandardItem(QString::number(row)));
                  for (int col = 1; col < 7; col++)
                      items.append(new QStandardItem(QString::number(col)));
                  im.appendRow(items);
              }
          });
          return a.exec();
      }
      

      for example. Note how I let the table view be shown before I start appending rows. Same "fast" speed. So what have you tried? Try this and/or the previous one on your machine before analyzing any further,

      L 1 Reply Last reply
      0
      • JonBJ JonB

        @Lee908 said in How many kinds of inner signals are triggered in Qt when modify item in QStandardItemModel?:

        Did you try it at beginning?

        Yes, I had already done that:

        #include <QApplication>
        #include <QStandardItemModel>
        #include <QTableView>
        #include <QTimer>
        
        int main(int argc, char *argv[])
        {
            QApplication a(argc, argv);
            QTableView tv;
            QStandardItemModel im;
            im.setColumnCount(7);
            tv.setModel(&im);
            tv.show();
            QTimer::singleShot(0, [&im]() {
                for (int row = 0; row < 2000; row++)
                {
                    QList<QStandardItem *> items;
                    items.append(new QStandardItem(QString::number(row)));
                    for (int col = 1; col < 7; col++)
                        items.append(new QStandardItem(QString::number(col)));
                    im.appendRow(items);
                }
            });
            return a.exec();
        }
        

        for example. Note how I let the table view be shown before I start appending rows. Same "fast" speed. So what have you tried? Try this and/or the previous one on your machine before analyzing any further,

        L Offline
        L Offline
        Lee908
        wrote on last edited by
        #13

        @JonB said in How many kinds of inner signals are triggered in Qt when modify item in QStandardItemModel?:

        Same "fast" speed

        Really SAME??? Before setModel and after setModel. Does it only happen on my old pc?

        JonBJ 1 Reply Last reply
        0
        • L Lee908

          @JonB said in How many kinds of inner signals are triggered in Qt when modify item in QStandardItemModel?:

          Same "fast" speed

          Really SAME??? Before setModel and after setModel. Does it only happen on my old pc?

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

          @Lee908
          Yeah, "same" :)

          We need to be talking about the same code as each other, else all bets are off. Have you actually tried literally copying & pasting my two examples to yours? Do they differ for you? (I assume you do not have high start-up time.) Do either take you 2 seconds?

          I just tried 20,000 rows instead of 2,000. Same "instantaneous"! Then 200,000, that was the first one which took about 1 or 2 seconds, and that's with 100x as many rows as yours :) And it requires 2,000,000 (two million) rows before it takes about 20 seconds....

          L 1 Reply Last reply
          1
          • kkoehneK Offline
            kkoehneK Offline
            kkoehne
            Moderators
            wrote on last edited by
            #15

            Consider wrapping your changes to the model with beginResetModel() and endResetModel(). This should greatly reduce the updates needed when you add or remove cells one by one.

            Director R&D, The Qt Company

            L 1 Reply Last reply
            4
            • JonBJ JonB

              @Lee908
              Yeah, "same" :)

              We need to be talking about the same code as each other, else all bets are off. Have you actually tried literally copying & pasting my two examples to yours? Do they differ for you? (I assume you do not have high start-up time.) Do either take you 2 seconds?

              I just tried 20,000 rows instead of 2,000. Same "instantaneous"! Then 200,000, that was the first one which took about 1 or 2 seconds, and that's with 100x as many rows as yours :) And it requires 2,000,000 (two million) rows before it takes about 20 seconds....

              L Offline
              L Offline
              Lee908
              wrote on last edited by
              #16

              @JonB said in How many kinds of inner signals are triggered in Qt when modify item in QStandardItemModel?:

              Do they differ for you?

              Finding out the root cause!!! I set cells by calling setItem one by one, but not appendRow! After using appendRow, the time cost is basically the same whenever I set model. Thanks very much.

              JonBJ 1 Reply Last reply
              0
              • kkoehneK kkoehne

                Consider wrapping your changes to the model with beginResetModel() and endResetModel(). This should greatly reduce the updates needed when you add or remove cells one by one.

                L Offline
                L Offline
                Lee908
                wrote on last edited by
                #17

                @kkoehne said in How many kinds of inner signals are triggered in Qt when modify item in QStandardItemModel?:

                Consider wrapping your changes to the model with beginResetModel() and endResetModel()

                Yes, that's what I did. Thanks for your advice.

                1 Reply Last reply
                0
                • L Lee908

                  @JonB said in How many kinds of inner signals are triggered in Qt when modify item in QStandardItemModel?:

                  Do they differ for you?

                  Finding out the root cause!!! I set cells by calling setItem one by one, but not appendRow! After using appendRow, the time cost is basically the same whenever I set model. Thanks very much.

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

                  @Lee908 said in How many kinds of inner signals are triggered in Qt when modify item in QStandardItemModel?:

                  I set cells by calling setItem one by one, but not appendRow!

                  Do you mean you had code like this:

                              im.insertRow(row);
                              im.setItem(row, 0, new QStandardItem(QString::number(row)));
                              for (int col = 1; col < 7; col++)
                                  im.setItem(row, col, new QStandardItem(QString::number(col)));
                  

                  With this my 2,000 items are still much faster than yours, but at 20,000 there is a noticeable delay.

                  Since you asked about "what signals are triggered", adding

                      QObject::connect(&im, &QStandardItemModel::rowsInserted, []() { qDebug() << "rowsInserted()"; });
                      QObject::connect(&im, &QStandardItemModel::itemChanged, []() { qDebug() << "itemChanged()"; });
                      QObject::connect(&im, &QStandardItemModel::dataChanged, []() { qDebug() << "dataChanged()"; });
                  

                  shows you the relevant signals here. With my appendRow() of a built row there is only one rowsInserted() signal per row added. With your add-row-then-change-items there are additionally 7 changedItem() and dataChanged() signals per each row, and these seem to be "expensive" in terms of what the table view does with them. @kkoehne's beginResetModel() (requires sub-classing) would avoid these signals, hence the speed, and perhaps desirable, but I would add the rows already filled with items in any case.

                  L 1 Reply Last reply
                  2
                  • JonBJ JonB

                    @Lee908 said in How many kinds of inner signals are triggered in Qt when modify item in QStandardItemModel?:

                    I set cells by calling setItem one by one, but not appendRow!

                    Do you mean you had code like this:

                                im.insertRow(row);
                                im.setItem(row, 0, new QStandardItem(QString::number(row)));
                                for (int col = 1; col < 7; col++)
                                    im.setItem(row, col, new QStandardItem(QString::number(col)));
                    

                    With this my 2,000 items are still much faster than yours, but at 20,000 there is a noticeable delay.

                    Since you asked about "what signals are triggered", adding

                        QObject::connect(&im, &QStandardItemModel::rowsInserted, []() { qDebug() << "rowsInserted()"; });
                        QObject::connect(&im, &QStandardItemModel::itemChanged, []() { qDebug() << "itemChanged()"; });
                        QObject::connect(&im, &QStandardItemModel::dataChanged, []() { qDebug() << "dataChanged()"; });
                    

                    shows you the relevant signals here. With my appendRow() of a built row there is only one rowsInserted() signal per row added. With your add-row-then-change-items there are additionally 7 changedItem() and dataChanged() signals per each row, and these seem to be "expensive" in terms of what the table view does with them. @kkoehne's beginResetModel() (requires sub-classing) would avoid these signals, hence the speed, and perhaps desirable, but I would add the rows already filled with items in any case.

                    L Offline
                    L Offline
                    Lee908
                    wrote on last edited by Lee908
                    #19

                    @JonB said in How many kinds of inner signals are triggered in Qt when modify item in QStandardItemModel?:

                    Do you mean you had code like this:

                    I had a class inherited QStandardItemModel. Firstly, I wrapped a function to add items just like:

                    void MyTableModel::Update()
                    {
                      ...
                      for(int i = 0; i < rowCount; i++)
                      {
                        QStandardItem* item1 = new QStandardItem("xx");
                        item1 ->setEditable(...);
                        setItem(i, 0, item1 );
                    
                        QStandardItem* item2 = new QStandardItem("xx");
                        item2 ->setFlags(...);
                        setItem(i, 1, item2 );
                    
                        ...
                        QStandardItem* item7 = new QStandardItem("xx");
                        item7 ->setCheckable(...);
                        setItem(i, 6, item7 );
                      }
                    }
                    

                    After using appendRow instead of setItem, the time is shorter significantly.

                    beginResetModel() (requires sub-classing) would avoid these signals

                    How to avoid those signals? Can you provide me with some details?

                    jsulmJ 1 Reply Last reply
                    0
                    • L Lee908

                      @JonB said in How many kinds of inner signals are triggered in Qt when modify item in QStandardItemModel?:

                      Do you mean you had code like this:

                      I had a class inherited QStandardItemModel. Firstly, I wrapped a function to add items just like:

                      void MyTableModel::Update()
                      {
                        ...
                        for(int i = 0; i < rowCount; i++)
                        {
                          QStandardItem* item1 = new QStandardItem("xx");
                          item1 ->setEditable(...);
                          setItem(i, 0, item1 );
                      
                          QStandardItem* item2 = new QStandardItem("xx");
                          item2 ->setFlags(...);
                          setItem(i, 1, item2 );
                      
                          ...
                          QStandardItem* item7 = new QStandardItem("xx");
                          item7 ->setCheckable(...);
                          setItem(i, 6, item7 );
                        }
                      }
                      

                      After using appendRow instead of setItem, the time is shorter significantly.

                      beginResetModel() (requires sub-classing) would avoid these signals

                      How to avoid those signals? Can you provide me with some details?

                      jsulmJ Offline
                      jsulmJ Offline
                      jsulm
                      Lifetime Qt Champion
                      wrote on last edited by
                      #20

                      @Lee908 said in How many kinds of inner signals are triggered in Qt when modify item in QStandardItemModel?:

                      How to avoid those signals?

                      By calling beginResetModel(). As @JonB wrote you will need to subclass QStandardItemModel to be able to call it (it is a protected method).

                      https://forum.qt.io/topic/113070/qt-code-of-conduct

                      L 1 Reply Last reply
                      2
                      • jsulmJ jsulm

                        @Lee908 said in How many kinds of inner signals are triggered in Qt when modify item in QStandardItemModel?:

                        How to avoid those signals?

                        By calling beginResetModel(). As @JonB wrote you will need to subclass QStandardItemModel to be able to call it (it is a protected method).

                        L Offline
                        L Offline
                        Lee908
                        wrote on last edited by Lee908
                        #21

                        @jsulm

                        I just noticed that beginResetModel() is a built-in function of QAbstractItemModel... Thanks for all your help.

                        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
                        • Unsolved