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.
  • L Lee908

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

    OoI, what is your user going to do with 2,000 visually-presented rows?

    Surprised!!! Do you mean it can't support 2,000 visually-presented rows fluently in Qt???...

    JonBJ Online
    JonBJ Online
    JonB
    wrote on last edited by
    #9

    @Lee908
    The following code:

    #include <QApplication>
    #include <QStandardItemModel>
    #include <QTableView>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        QTableView tv;
        QStandardItemModel im;
        im.setColumnCount(7);
        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);
        }
        tv.setModel(&im);
        tv.show();
        return a.exec();
    }
    

    populates and shows 2,000 rows of 7 columns "instantaneously" on my very slow Linux box with Qt 5.15. What are you doing different from this?

    L 1 Reply Last reply
    0
    • JonBJ JonB

      @Lee908
      The following code:

      #include <QApplication>
      #include <QStandardItemModel>
      #include <QTableView>
      
      int main(int argc, char *argv[])
      {
          QApplication a(argc, argv);
          QTableView tv;
          QStandardItemModel im;
          im.setColumnCount(7);
          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);
          }
          tv.setModel(&im);
          tv.show();
          return a.exec();
      }
      

      populates and shows 2,000 rows of 7 columns "instantaneously" on my very slow Linux box with Qt 5.15. What are you doing different from this?

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

      @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 1 Reply Last reply
      0
      • 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 Online
          JonBJ Online
          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 Online
              JonBJ Online
              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 Online
                      JonBJ Online
                      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