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. Lagging window/gui when using realtime table view
Qt 6.11 is out! See what's new in the release blog

Lagging window/gui when using realtime table view

Scheduled Pinned Locked Moved Solved General and Desktop
26 Posts 4 Posters 6.0k Views 3 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.
  • M Mr Gisa

    @JKSH said in Lagging window/gui when using realtime table view:

    I'm guessing you meant: The program lags when resultAvailable() is emitted (which runs addResult()). In contrast, it doesn't lag if you simply print the Result object's data to the console (using printf() or std::cout or qDebug()) without emitting the signal.

    Exactly, sorry for the wrong description.

    Quick check: What happens if you don't link your model to the table view (comment out tableView->setModel(...)? Does the UI still lag?

    It doesn't lag at all.

    That is the entire model code:

    #include "resultsmodel.hpp"
    #include "result.hpp"
    
    ResultsModel::ResultsModel(QObject *parent) : QAbstractTableModel(parent)
    {
        // ...
    }
    
    int ResultsModel::rowCount(const QModelIndex &) const
    {
        return mResults.size();
    }
    
    int ResultsModel::columnCount(const QModelIndex &) const
    {
        return 5;
    }
    
    QVariant ResultsModel::data(const QModelIndex &index, int role) const
    {
        if (! index.isValid()) {
            return QVariant();
        }
    
        if (index.row() >= mResults.size() || index.row() < 0) {
            return QVariant();
        }
    
        auto result = mResults.at(index.row());
    
        if (role == Qt::DisplayRole) {
            switch (index.column()) {
            case 0:
                return result->filename().isEmpty() ? "?" : result->filename();
                break;
    
            case 1:
                return result->url();
                break;
    
            case 2:
                return result->source();
                break;
    
            case 3:
                return result->fileSize().isEmpty() ? "?" : result->fileSize();
                break;
    
            case 4:
                return result->isOnline() ? "Yes" : "No";
                break;
            }
        }
    
        return QVariant();
    }
    
    bool ResultsModel::setData(const QModelIndex &, const QVariant &, int)
    {
        return false;
    }
    
    QVariant ResultsModel::headerData(int section, Qt::Orientation orientation, int role) const
    {
        if (role != Qt::DisplayRole) {
            return QVariant();
        }
    
        if (orientation == Qt::Horizontal) {
            switch (section) {
            case 0:
                return tr("Filename");
                break;
    
            case 1:
                return tr("Url");
                break;
    
            case 2:
                return tr("Source");
                break;
    
            case 3:
                return tr("Size");
                break;
    
            case 4:
                return tr("Online");
                break;
    
            default:
                return QVariant();
                break;
            }
        }
    
        return QVariant();
    }
    
    Qt::ItemFlags ResultsModel::flags(const QModelIndex &index) const
    {
        if (! index.isValid()) {
            return Qt::ItemIsEnabled;
        }
    
        return QAbstractTableModel::flags(index);
    }
    
    void ResultsModel::addResult(Result *result)
    {
        if (mResults.contains(result)) {
            return;
        }
    
        auto index = mResults.size();
    
        beginInsertRows(QModelIndex(), index, index);
        mResults << result;
        endInsertRows();
    }
    
    void ResultsModel::reset()
    {
        beginResetModel();
        qDeleteAll(mResults.begin(), mResults.end());
        mResults.clear();
        endResetModel();
    }
    
    JKSHJ Offline
    JKSHJ Offline
    JKSH
    Moderators
    wrote on last edited by
    #6

    @Mr-Gisa said in Lagging window/gui when using realtime table view:

    @JKSH said in Lagging window/gui when using realtime table view:

    I'm guessing you meant: The program lags when resultAvailable() is emitted (which runs addResult()). In contrast, it doesn't lag if you simply print the Result object's data to the console (using printf() or std::cout or qDebug()) without emitting the signal.

    Exactly, sorry for the wrong description.

    Quick check: What happens if you don't link your model to the table view (comment out tableView->setModel(...)? Does the UI still lag?

    It doesn't lag at all.

    That is the entire model code:

    Your code looks quite straightforward and clean.

    I'm wondering if beginInsertRows() is being called too frequently. Some things you can try:

    • Do some very basic profiling: Make every call to addResult() print a message to the console. Roughly how frequently is it being called?

    • Use batched updates. Instead of doing beginInsertRows() - append - endInsertRows() every single time the resultAvailable() signal is emitted, store the new result in a temporary location but don't add it to mResults yet. Every 0.5s, add all the new results at once:

      1. Call beginInsertRows() once
      2. Add all the available results
      3. Call endInsertRows() once

    Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

    M 1 Reply Last reply
    2
    • JKSHJ JKSH

      @Mr-Gisa said in Lagging window/gui when using realtime table view:

      @JKSH said in Lagging window/gui when using realtime table view:

      I'm guessing you meant: The program lags when resultAvailable() is emitted (which runs addResult()). In contrast, it doesn't lag if you simply print the Result object's data to the console (using printf() or std::cout or qDebug()) without emitting the signal.

      Exactly, sorry for the wrong description.

      Quick check: What happens if you don't link your model to the table view (comment out tableView->setModel(...)? Does the UI still lag?

      It doesn't lag at all.

      That is the entire model code:

      Your code looks quite straightforward and clean.

      I'm wondering if beginInsertRows() is being called too frequently. Some things you can try:

      • Do some very basic profiling: Make every call to addResult() print a message to the console. Roughly how frequently is it being called?

      • Use batched updates. Instead of doing beginInsertRows() - append - endInsertRows() every single time the resultAvailable() signal is emitted, store the new result in a temporary location but don't add it to mResults yet. Every 0.5s, add all the new results at once:

        1. Call beginInsertRows() once
        2. Add all the available results
        3. Call endInsertRows() once
      M Offline
      M Offline
      Mr Gisa
      wrote on last edited by Mr Gisa
      #7

      @JKSH with batched results you mean like this? https://doc.qt.io/qt-5/qtwidgets-itemviews-fetchmore-example.html

      About the how many times the addResult is being called, it's a lot, it's like every half second a new result is added.

      1 Reply Last reply
      0
      • M Mr Gisa

        @JKSH said in Lagging window/gui when using realtime table view:

        I'm guessing you meant: The program lags when resultAvailable() is emitted (which runs addResult()). In contrast, it doesn't lag if you simply print the Result object's data to the console (using printf() or std::cout or qDebug()) without emitting the signal.

        Exactly, sorry for the wrong description.

        Quick check: What happens if you don't link your model to the table view (comment out tableView->setModel(...)? Does the UI still lag?

        It doesn't lag at all.

        That is the entire model code:

        #include "resultsmodel.hpp"
        #include "result.hpp"
        
        ResultsModel::ResultsModel(QObject *parent) : QAbstractTableModel(parent)
        {
            // ...
        }
        
        int ResultsModel::rowCount(const QModelIndex &) const
        {
            return mResults.size();
        }
        
        int ResultsModel::columnCount(const QModelIndex &) const
        {
            return 5;
        }
        
        QVariant ResultsModel::data(const QModelIndex &index, int role) const
        {
            if (! index.isValid()) {
                return QVariant();
            }
        
            if (index.row() >= mResults.size() || index.row() < 0) {
                return QVariant();
            }
        
            auto result = mResults.at(index.row());
        
            if (role == Qt::DisplayRole) {
                switch (index.column()) {
                case 0:
                    return result->filename().isEmpty() ? "?" : result->filename();
                    break;
        
                case 1:
                    return result->url();
                    break;
        
                case 2:
                    return result->source();
                    break;
        
                case 3:
                    return result->fileSize().isEmpty() ? "?" : result->fileSize();
                    break;
        
                case 4:
                    return result->isOnline() ? "Yes" : "No";
                    break;
                }
            }
        
            return QVariant();
        }
        
        bool ResultsModel::setData(const QModelIndex &, const QVariant &, int)
        {
            return false;
        }
        
        QVariant ResultsModel::headerData(int section, Qt::Orientation orientation, int role) const
        {
            if (role != Qt::DisplayRole) {
                return QVariant();
            }
        
            if (orientation == Qt::Horizontal) {
                switch (section) {
                case 0:
                    return tr("Filename");
                    break;
        
                case 1:
                    return tr("Url");
                    break;
        
                case 2:
                    return tr("Source");
                    break;
        
                case 3:
                    return tr("Size");
                    break;
        
                case 4:
                    return tr("Online");
                    break;
        
                default:
                    return QVariant();
                    break;
                }
            }
        
            return QVariant();
        }
        
        Qt::ItemFlags ResultsModel::flags(const QModelIndex &index) const
        {
            if (! index.isValid()) {
                return Qt::ItemIsEnabled;
            }
        
            return QAbstractTableModel::flags(index);
        }
        
        void ResultsModel::addResult(Result *result)
        {
            if (mResults.contains(result)) {
                return;
            }
        
            auto index = mResults.size();
        
            beginInsertRows(QModelIndex(), index, index);
            mResults << result;
            endInsertRows();
        }
        
        void ResultsModel::reset()
        {
            beginResetModel();
            qDeleteAll(mResults.begin(), mResults.end());
            mResults.clear();
            endResetModel();
        }
        
        Christian EhrlicherC Online
        Christian EhrlicherC Online
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote on last edited by
        #8

        @Mr-Gisa said in Lagging window/gui when using realtime table view:

        if (mResults.contains(result)) {
            return;
        }
        

        This is not a good idea...

        1. why should addResult() called twice with the same pointer? This can only happen due to wrong code on your side
        2. a linear lookup is maybe fast for < 100 lookups but not for huge data.

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

        1 Reply Last reply
        2
        • M Mr Gisa

          @JKSH said in Lagging window/gui when using realtime table view:

          I'm guessing you meant: The program lags when resultAvailable() is emitted (which runs addResult()). In contrast, it doesn't lag if you simply print the Result object's data to the console (using printf() or std::cout or qDebug()) without emitting the signal.

          Exactly, sorry for the wrong description.

          Quick check: What happens if you don't link your model to the table view (comment out tableView->setModel(...)? Does the UI still lag?

          It doesn't lag at all.

          That is the entire model code:

          #include "resultsmodel.hpp"
          #include "result.hpp"
          
          ResultsModel::ResultsModel(QObject *parent) : QAbstractTableModel(parent)
          {
              // ...
          }
          
          int ResultsModel::rowCount(const QModelIndex &) const
          {
              return mResults.size();
          }
          
          int ResultsModel::columnCount(const QModelIndex &) const
          {
              return 5;
          }
          
          QVariant ResultsModel::data(const QModelIndex &index, int role) const
          {
              if (! index.isValid()) {
                  return QVariant();
              }
          
              if (index.row() >= mResults.size() || index.row() < 0) {
                  return QVariant();
              }
          
              auto result = mResults.at(index.row());
          
              if (role == Qt::DisplayRole) {
                  switch (index.column()) {
                  case 0:
                      return result->filename().isEmpty() ? "?" : result->filename();
                      break;
          
                  case 1:
                      return result->url();
                      break;
          
                  case 2:
                      return result->source();
                      break;
          
                  case 3:
                      return result->fileSize().isEmpty() ? "?" : result->fileSize();
                      break;
          
                  case 4:
                      return result->isOnline() ? "Yes" : "No";
                      break;
                  }
              }
          
              return QVariant();
          }
          
          bool ResultsModel::setData(const QModelIndex &, const QVariant &, int)
          {
              return false;
          }
          
          QVariant ResultsModel::headerData(int section, Qt::Orientation orientation, int role) const
          {
              if (role != Qt::DisplayRole) {
                  return QVariant();
              }
          
              if (orientation == Qt::Horizontal) {
                  switch (section) {
                  case 0:
                      return tr("Filename");
                      break;
          
                  case 1:
                      return tr("Url");
                      break;
          
                  case 2:
                      return tr("Source");
                      break;
          
                  case 3:
                      return tr("Size");
                      break;
          
                  case 4:
                      return tr("Online");
                      break;
          
                  default:
                      return QVariant();
                      break;
                  }
              }
          
              return QVariant();
          }
          
          Qt::ItemFlags ResultsModel::flags(const QModelIndex &index) const
          {
              if (! index.isValid()) {
                  return Qt::ItemIsEnabled;
              }
          
              return QAbstractTableModel::flags(index);
          }
          
          void ResultsModel::addResult(Result *result)
          {
              if (mResults.contains(result)) {
                  return;
              }
          
              auto index = mResults.size();
          
              beginInsertRows(QModelIndex(), index, index);
              mResults << result;
              endInsertRows();
          }
          
          void ResultsModel::reset()
          {
              beginResetModel();
              qDeleteAll(mResults.begin(), mResults.end());
              mResults.clear();
              endResetModel();
          }
          
          Christian EhrlicherC Online
          Christian EhrlicherC Online
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on last edited by
          #9

          @Mr-Gisa said in Lagging window/gui when using realtime table view:

          if (! index.isValid()) {
              return QVariant();
          }
          
          if (index.row() >= mResults.size() || index.row() < 0) {
              return QVariant();
          }
          
          auto result = mResults.at(index.row());
          

          And here I would first check for the role, then the bounds and at last for the validity since this is the most expensive operation here.

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

          1 Reply Last reply
          2
          • M Offline
            M Offline
            Mr Gisa
            wrote on last edited by
            #10

            @Christian-Ehrlicher I made the changes you pointed out and it helped a lot, it's still lagging, but way less than it was before. I can feel the gui freezing when trying to move, and as it's a lot of incoming data per second in the model you can really feel the lag in the gui.
            I think you know a software called Wireshark, it was made using Qt and their table receives A LOT (way more than mine) of packets information and it doesn't lag at all, but in my application I can feel the lag when I try to move the window around while the results are being displayed in the table.

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

              Another idea is to collect some results and add them once in a second (or every n seconds) instead every single one.

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

              1 Reply Last reply
              2
              • M Offline
                M Offline
                Mr Gisa
                wrote on last edited by Mr Gisa
                #12

                I realized something. When I compile in release mode and run the application out of the Qt, like running the actual executable it doesn't lag. Why is that?

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

                  Because now the compiler don't need to generate debug information and compiles your code with optimizations.

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

                  1 Reply Last reply
                  2
                  • M Offline
                    M Offline
                    Mr Gisa
                    wrote on last edited by
                    #14

                    You think I should leave that way getting results at real time or do the batched thing? What is the best alternative here?

                    mrjjM 1 Reply Last reply
                    0
                    • M Mr Gisa

                      You think I should leave that way getting results at real time or do the batched thing? What is the best alternative here?

                      mrjjM Offline
                      mrjjM Offline
                      mrjj
                      Lifetime Qt Champion
                      wrote on last edited by
                      #15

                      @Mr-Gisa
                      Since you are planning on even higher payloads, you should test if release mode
                      can handle that or you simply need to batch them.

                      1 Reply Last reply
                      1
                      • M Offline
                        M Offline
                        Mr Gisa
                        wrote on last edited by
                        #16

                        It will have on average 100 or 200 thousand results.

                        mrjjM 1 Reply Last reply
                        0
                        • M Mr Gisa

                          It will have on average 100 or 200 thousand results.

                          mrjjM Offline
                          mrjjM Offline
                          mrjj
                          Lifetime Qt Champion
                          wrote on last edited by
                          #17

                          @Mr-Gisa
                          and are you testing with that many now?

                          1 Reply Last reply
                          0
                          • M Offline
                            M Offline
                            Mr Gisa
                            wrote on last edited by
                            #18

                            5~10 thousands, I can't get to 100~200 cause I have to code the other APIs, but with that it's working normally at this point.

                            mrjjM 1 Reply Last reply
                            0
                            • M Mr Gisa

                              5~10 thousands, I can't get to 100~200 cause I have to code the other APIs, but with that it's working normally at this point.

                              mrjjM Offline
                              mrjjM Offline
                              mrjj
                              Lifetime Qt Champion
                              wrote on last edited by
                              #19

                              @Mr-Gisa
                              Ok, but you can postpone it until you have test data then and work on the other parts.

                              1 Reply Last reply
                              0
                              • M Offline
                                M Offline
                                Mr Gisa
                                wrote on last edited by
                                #20

                                Exactly, that is what I'm going to do. Thank you all for your help. If anything happen in the future I'll say it here.
                                I'm also going to get a copy with a friend of mine of his Intel Parallel Studio 2018 to check a few things in the application, I hope it works with Qt.

                                mrjjM 1 Reply Last reply
                                0
                                • M Mr Gisa

                                  Exactly, that is what I'm going to do. Thank you all for your help. If anything happen in the future I'll say it here.
                                  I'm also going to get a copy with a friend of mine of his Intel Parallel Studio 2018 to check a few things in the application, I hope it works with Qt.

                                  mrjjM Offline
                                  mrjjM Offline
                                  mrjj
                                  Lifetime Qt Champion
                                  wrote on last edited by
                                  #21

                                  @Mr-Gisa said in Lagging window/gui when using realtime table view:

                                  Intel Parallel Studio 2018

                                  Well its a compiler so good chance it can compile Qt.

                                  1 Reply Last reply
                                  0
                                  • M Offline
                                    M Offline
                                    Mr Gisa
                                    wrote on last edited by
                                    #22

                                    I'm not going to use the compiler, but the Intel® Inspector and Intel® VTune™ Amplifier.

                                    Intel® Inspector: Memory and Thread Debugger
                                    Intel® VTune™ Amplifier: Performance Profiler

                                    mrjjM 1 Reply Last reply
                                    0
                                    • M Mr Gisa

                                      I'm not going to use the compiler, but the Intel® Inspector and Intel® VTune™ Amplifier.

                                      Intel® Inspector: Memory and Thread Debugger
                                      Intel® VTune™ Amplifier: Performance Profiler

                                      mrjjM Offline
                                      mrjjM Offline
                                      mrjj
                                      Lifetime Qt Champion
                                      wrote on last edited by
                                      #23

                                      @Mr-Gisa
                                      Ok, but can it do it without touching the source code?

                                      1 Reply Last reply
                                      0
                                      • M Offline
                                        M Offline
                                        Mr Gisa
                                        wrote on last edited by
                                        #24

                                        Yes, but you can also specify the source code and it will show you the places that it has leaks and is slow, stuff like that.

                                        mrjjM 1 Reply Last reply
                                        0
                                        • M Mr Gisa

                                          Yes, but you can also specify the source code and it will show you the places that it has leaks and is slow, stuff like that.

                                          mrjjM Offline
                                          mrjjM Offline
                                          mrjj
                                          Lifetime Qt Champion
                                          wrote on last edited by
                                          #25

                                          @Mr-Gisa
                                          Sounds really good. Never tested it.

                                          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