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. Update 2 QTableWidgets simultaneously to reduce the run time

Update 2 QTableWidgets simultaneously to reduce the run time

Scheduled Pinned Locked Moved Solved General and Desktop
10 Posts 3 Posters 793 Views 2 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.
  • D Offline
    D Offline
    Dev-G
    wrote on last edited by
    #1

    I have 2 sections which display data coming from same resource (basically the resource could be divided into two chunks) I measured each section run time as following 10ms filling data, 60ms drawing out result, 5ms, 30ms respectively. If only one thread can process UI that means 70ms + 35ms a total 105ms run time, ideally I prefer display the data seamlessly to reduce the total time to 70ms since 35ms is less than 70ms?

    JonBJ D 2 Replies Last reply
    0
    • D Dev-G

      I have 2 sections which display data coming from same resource (basically the resource could be divided into two chunks) I measured each section run time as following 10ms filling data, 60ms drawing out result, 5ms, 30ms respectively. If only one thread can process UI that means 70ms + 35ms a total 105ms run time, ideally I prefer display the data seamlessly to reduce the total time to 70ms since 35ms is less than 70ms?

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

      @Dev-G
      As @Chris-Kawa told you in your other thread Qt does not allow access to the UI from multiple threads. That's just how it is, whether you like it or not.

      You can offload as much non-UI computation as you like to secondary threads, so if you can do that it may help. But such threads will have to send a signal to the main thread when it's ready for that to do whatever UI work with the results.

      D 1 Reply Last reply
      2
      • JonBJ JonB

        @Dev-G
        As @Chris-Kawa told you in your other thread Qt does not allow access to the UI from multiple threads. That's just how it is, whether you like it or not.

        You can offload as much non-UI computation as you like to secondary threads, so if you can do that it may help. But such threads will have to send a signal to the main thread when it's ready for that to do whatever UI work with the results.

        D Offline
        D Offline
        Dev-G
        wrote on last edited by
        #3

        @JonB You mean Object.moveToThread(&someThread) then
        QObject::connect(&someThread, &QThread::started, &myTableWidget, SLOT()); something like that?

        @JonB said in Update 2 QTableWidgets simultaneously to reduce the run time:

        to do whatever UI work with the results.

        Can you explain this in detail? I kind of confused with UI work and fill data into QTableWidget. For example, table->setItem(i, j, item) this consider UI work or data preparation? My understanding is data preparation, correct me if I am wrong.

        JonBJ 1 Reply Last reply
        0
        • D Dev-G

          @JonB You mean Object.moveToThread(&someThread) then
          QObject::connect(&someThread, &QThread::started, &myTableWidget, SLOT()); something like that?

          @JonB said in Update 2 QTableWidgets simultaneously to reduce the run time:

          to do whatever UI work with the results.

          Can you explain this in detail? I kind of confused with UI work and fill data into QTableWidget. For example, table->setItem(i, j, item) this consider UI work or data preparation? My understanding is data preparation, correct me if I am wrong.

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

          @Dev-G
          Nope, I'm afraid that is very much a "UI" call, and must never be done from a secondary thread. That could calculate what it is you want to put into the model data, but cannot call anything like QTableWidget::setItem() directly. The thread would have to emit a signal when the data was ready (either passed as an argument to the signal, or stored in some data structure which can safely be shared with the UI thread e.g. using a mutex). The UI must put a slot on that signal which when called picks up the data and puts it into the QTableWidget for display.

          First things first. If you are concerned about speed you need to ditch QTableWidget. It is a "convenience" class for simple cases, not suitable for optimization. It does not do anything you cannot do yourself, and better. It comprises a QTableView plus an in-built model of its own. Quite unsuitable for anything multi-threaded.

          So you will want to change over to a QTableView and attach that to your own model derived from QAbstractItem/TableModel, which you design to be as convenient as possible to your data needs.

          To keep the secondary thread quite separate from anything UI, do not allow it to #include anything from QWidget or QGui, either directly or via anything else of your own which includes them. You will soon find what you cannot use in this case!

          Take an example from me. I have been working on prime numbers. they are slow to generate (certainly as you get into the hundreds of billions!). Let's say I want to show a list of them and I can break the calculation into multiple separate, concurrent threads. Then these threads calculate one or a group of new numbers and emit a signal when new ones are available. The UI places a slot on this, and when called that puts them into the model and display them in the view.

          D 1 Reply Last reply
          4
          • JonBJ JonB referenced this topic on
          • JonBJ JonB

            @Dev-G
            Nope, I'm afraid that is very much a "UI" call, and must never be done from a secondary thread. That could calculate what it is you want to put into the model data, but cannot call anything like QTableWidget::setItem() directly. The thread would have to emit a signal when the data was ready (either passed as an argument to the signal, or stored in some data structure which can safely be shared with the UI thread e.g. using a mutex). The UI must put a slot on that signal which when called picks up the data and puts it into the QTableWidget for display.

            First things first. If you are concerned about speed you need to ditch QTableWidget. It is a "convenience" class for simple cases, not suitable for optimization. It does not do anything you cannot do yourself, and better. It comprises a QTableView plus an in-built model of its own. Quite unsuitable for anything multi-threaded.

            So you will want to change over to a QTableView and attach that to your own model derived from QAbstractItem/TableModel, which you design to be as convenient as possible to your data needs.

            To keep the secondary thread quite separate from anything UI, do not allow it to #include anything from QWidget or QGui, either directly or via anything else of your own which includes them. You will soon find what you cannot use in this case!

            Take an example from me. I have been working on prime numbers. they are slow to generate (certainly as you get into the hundreds of billions!). Let's say I want to show a list of them and I can break the calculation into multiple separate, concurrent threads. Then these threads calculate one or a group of new numbers and emit a signal when new ones are available. The UI places a slot on this, and when called that puts them into the model and display them in the view.

            D Offline
            D Offline
            Dev-G
            wrote on last edited by
            #5

            @JonB Hi, what's the TableView + StandardModelItem like? I think I tried below model and TableView.

            DashTableModel::DashTableModel()
            {

            }
            DashTableModel::~DashTableModel()
            {

            }

            QVariant DashTableModel::data(const QModelIndex &index, int role) const{
            if (!index.isValid()) {
            return QVariant();
            }
            if (role == Qt::TextAlignmentRole) {
            return int(Qt::AlignLeft | Qt::AlignVCenter);
            } else if (role == Qt::DisplayRole) {
            return QStandardItemModel::data(index, role);
            } else if (role == Qt::BackgroundRole) {

            }
            return QVariant();
            

            }

            =================================================================================
            QTableView *tableView = new QTableView(widget);
            tableView->setGeometry(10, 10, 400, 300);

            QStandardItemModel *model = new QStandardItemModel();
            
            model->setRowCount(18);
            model->setColumnCount(28);
            
            model->setHeaderData(0, Qt::Horizontal, "Name");
            model->setHeaderData(1, Qt::Horizontal, "Age");
            
            model->setData(model->index(0, 0), "Tom");
            model->setData(model->index(0, 1), 20);
            model->setData(model->index(1, 0), "Jerry");
            model->setData(model->index(1, 1), 18);
            model->setData(model->index(2, 0), "Mike");
            model->setData(model->index(2, 1), 25);
            
            tableView->setModel(model);
            
            QObject::connect(model, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), tableView, SLOT(update()));
            

            ============================================================================

            in the update() I will do something like below

            model->setData(model->index(0, 0), "A");
            model->setData(model->index(0, 1), 200);
            model->setData(model->index(1, 0), "B");
            model->setData(model->index(1, 1), 180);
            model->setData(model->index(2, 0), "C");
            model->setData(model->index(2, 1), 250);
            

            It seems running slower than QTableWidget. What's wrong? Update() function should be triggered every 60ms using a Timer.

            SGaistS 1 Reply Last reply
            0
            • D Dev-G

              @JonB Hi, what's the TableView + StandardModelItem like? I think I tried below model and TableView.

              DashTableModel::DashTableModel()
              {

              }
              DashTableModel::~DashTableModel()
              {

              }

              QVariant DashTableModel::data(const QModelIndex &index, int role) const{
              if (!index.isValid()) {
              return QVariant();
              }
              if (role == Qt::TextAlignmentRole) {
              return int(Qt::AlignLeft | Qt::AlignVCenter);
              } else if (role == Qt::DisplayRole) {
              return QStandardItemModel::data(index, role);
              } else if (role == Qt::BackgroundRole) {

              }
              return QVariant();
              

              }

              =================================================================================
              QTableView *tableView = new QTableView(widget);
              tableView->setGeometry(10, 10, 400, 300);

              QStandardItemModel *model = new QStandardItemModel();
              
              model->setRowCount(18);
              model->setColumnCount(28);
              
              model->setHeaderData(0, Qt::Horizontal, "Name");
              model->setHeaderData(1, Qt::Horizontal, "Age");
              
              model->setData(model->index(0, 0), "Tom");
              model->setData(model->index(0, 1), 20);
              model->setData(model->index(1, 0), "Jerry");
              model->setData(model->index(1, 1), 18);
              model->setData(model->index(2, 0), "Mike");
              model->setData(model->index(2, 1), 25);
              
              tableView->setModel(model);
              
              QObject::connect(model, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), tableView, SLOT(update()));
              

              ============================================================================

              in the update() I will do something like below

              model->setData(model->index(0, 0), "A");
              model->setData(model->index(0, 1), 200);
              model->setData(model->index(1, 0), "B");
              model->setData(model->index(1, 1), 180);
              model->setData(model->index(2, 0), "C");
              model->setData(model->index(2, 1), 250);
              

              It seems running slower than QTableWidget. What's wrong? Update() function should be triggered every 60ms using a Timer.

              SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #6

              @Dev-G hi,

              Why are you manually triggering updates of your view from your model ? It's already handled by Qt. What you are doing here is requesting additional repaints for nothing.

              As for your technique, you are not doing things optimally for your end goal. You should rather take the time to understand how fast your data are coming in, how much of it will be useful for your user and more important, does it make any sense to fill your model and your view that fast for your users ? When you have fast inputs, it doesn't make any sense to try to show them as soon as they arrive. Work in batches, use a custom model and load several rows worth of data regularly rather than trying to push everything as fast as possible. You are not designing an MMO FPS.

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

              D 2 Replies Last reply
              1
              • SGaistS SGaist

                @Dev-G hi,

                Why are you manually triggering updates of your view from your model ? It's already handled by Qt. What you are doing here is requesting additional repaints for nothing.

                As for your technique, you are not doing things optimally for your end goal. You should rather take the time to understand how fast your data are coming in, how much of it will be useful for your user and more important, does it make any sense to fill your model and your view that fast for your users ? When you have fast inputs, it doesn't make any sense to try to show them as soon as they arrive. Work in batches, use a custom model and load several rows worth of data regularly rather than trying to push everything as fast as possible. You are not designing an MMO FPS.

                D Offline
                D Offline
                Dev-G
                wrote on last edited by
                #7

                @SGaist True, I am not doing a game development, but I need the program to be like 20FPS, I am doing some live monitoring which needs to refresh the screen frequently and very fast(closer to 20FPS). Here is some information to fill your question. The time relate to data(send request + receive data) is about 30ms which will be a uint8_t bit stream size over 1000 elements. NO JUNK in the source data.

                You might say I could use plot to achieve monitoring feature, but that's just part of the monitoring. As you may find out from above, I need a table like heat map on the screen( I need to see each cell's value and color) I did try QCustomPlot's QCPColorMap, not ideal cuz I need to override some method in order to show value on QCPColorMap.

                Does those information help?

                1 Reply Last reply
                0
                • D Dev-G

                  I have 2 sections which display data coming from same resource (basically the resource could be divided into two chunks) I measured each section run time as following 10ms filling data, 60ms drawing out result, 5ms, 30ms respectively. If only one thread can process UI that means 70ms + 35ms a total 105ms run time, ideally I prefer display the data seamlessly to reduce the total time to 70ms since 35ms is less than 70ms?

                  D Offline
                  D Offline
                  Dev-G
                  wrote on last edited by
                  #8

                  @Dev-G Add on to this thread. Just curious I have a loop running 500 times and I find out
                  item->setText(QString::number(11));
                  this line of code is extremally slow like 60ms slower, why is that?

                  1 Reply Last reply
                  0
                  • SGaistS SGaist

                    @Dev-G hi,

                    Why are you manually triggering updates of your view from your model ? It's already handled by Qt. What you are doing here is requesting additional repaints for nothing.

                    As for your technique, you are not doing things optimally for your end goal. You should rather take the time to understand how fast your data are coming in, how much of it will be useful for your user and more important, does it make any sense to fill your model and your view that fast for your users ? When you have fast inputs, it doesn't make any sense to try to show them as soon as they arrive. Work in batches, use a custom model and load several rows worth of data regularly rather than trying to push everything as fast as possible. You are not designing an MMO FPS.

                    D Offline
                    D Offline
                    Dev-G
                    wrote on last edited by
                    #9

                    @SGaist Hi, my bad, I found a bug in my code.. The reason my code was running slow due to I have header set to ResizeToContent, so whenever I am updating data, it recalc the width which slows the program I suppose?

                    SGaistS 1 Reply Last reply
                    0
                    • D Dev-G has marked this topic as solved on
                    • D Dev-G

                      @SGaist Hi, my bad, I found a bug in my code.. The reason my code was running slow due to I have header set to ResizeToContent, so whenever I am updating data, it recalc the width which slows the program I suppose?

                      SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      @Dev-G correct and depending on the amount of data and the speed to retrieve them it can take some time.

                      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