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. Smooth QTableView when periodically adding new data
Forum Updated to NodeBB v4.3 + New Features

Smooth QTableView when periodically adding new data

Scheduled Pinned Locked Moved Unsolved General and Desktop
2 Posts 2 Posters 268 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.
  • T Offline
    T Offline
    tilz0R
    wrote on last edited by
    #1

    I'm building an application similar to WireShark, with data coming in periodic (100-200ms range) frames.

    I've notices that when there is more data than table can hold, scroll is not smooth, and moving the complete window isn't smooth either. Disabling the periodic add to the table, makes everything working well again.
    I've tried to play with different beforeInsert and afterInsert hooks, but was not successful at all.

    There is an auto-scroll feature, which scrolls the table if vertical scroll is at the bottom before the insert event.

        /* Set tableview model */
        ui->table_can_logger->horizontalHeader()->setDefaultAlignment(Qt::AlignmentFlag::AlignLeft);
        ui->table_can_logger->horizontalHeader()->setStretchLastSection(true);
        ui->table_can_logger->resizeColumnsToContents();
        ui->table_can_logger->resizeRowsToContents();
        ui->table_can_logger->setSelectionBehavior(QAbstractItemView::SelectRows);
        ui->table_can_logger->verticalHeader()->setVisible(true);
        ui->table_can_logger->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeMode::Custom);
        ui->table_can_logger->verticalHeader()->setDefaultSectionSize(16);
        ui->table_can_logger->setShowGrid(false);
        ui->table_can_logger->setModel(model_can_logger);
    
    
        //Connection for auto scroll
        connect(model_can_logger, &QAbstractItemModel::rowsInserted, this, &ViewLogger::logger_table_rows_inserted);
        connect(model_can_logger, &QAbstractItemModel::rowsAboutToBeInserted, this,
                &ViewLogger::logger_table_rows_to_be_inserted);
    

    Model slots in the view

    void
    ViewLogger::logger_table_rows_to_be_inserted() {
        QScrollBar* scrollbar = ui->table_can_logger->verticalScrollBar();
        do_scroll_table = scrollbar->value() == scrollbar->maximum();
    }
    void
    ViewLogger::logger_table_rows_inserted() {
        if (do_scroll_table) {
            QTimer::singleShot(50, ui->table_can_logger, &QTableView::scrollToBottom);
        }
    }
    

    My model append function, which adds new entry to the list, after it has been allocated with new:

    void
    CANLoggerDataModel::append(CANLoggerDataEntry* entry) {
        beginInsertRows(QModelIndex(), table_list.count(), table_list.count());
        table_list.append(entry);
        endInsertRows();
    }
    

    On every received message, I also have to check for some data, and for this reason I have a backward iterator in the model, too:

    void
    CANLoggerDataModel::canMsgSetSendAck(const ca_can_msg_ack_t* ack) {
        CANLoggerDataEntry* entry;
        QListIterator<CANLoggerDataEntry*> it(table_list);
        uint32_t len = table_list.count();
    
        it.toBack();
        while (it.hasPrevious() && len-- > 0) {
            entry = it.previous();
            if (entry->send_id == ack->uid) {
                entry->status = static_cast<ca_status_t>(ack->status);
                entry->message.time_sec = ack->time_sec;
                entry->message.time_usec = ack->time_usec;
                emit dataChanged(index(len, 0), index(len, columnCount() - 1));
                break;
            }
        }
    }
    

    What could cause the lagging events? What could be optimized to improve this?

    Thanks

    M 1 Reply Last reply
    0
    • T tilz0R

      I'm building an application similar to WireShark, with data coming in periodic (100-200ms range) frames.

      I've notices that when there is more data than table can hold, scroll is not smooth, and moving the complete window isn't smooth either. Disabling the periodic add to the table, makes everything working well again.
      I've tried to play with different beforeInsert and afterInsert hooks, but was not successful at all.

      There is an auto-scroll feature, which scrolls the table if vertical scroll is at the bottom before the insert event.

          /* Set tableview model */
          ui->table_can_logger->horizontalHeader()->setDefaultAlignment(Qt::AlignmentFlag::AlignLeft);
          ui->table_can_logger->horizontalHeader()->setStretchLastSection(true);
          ui->table_can_logger->resizeColumnsToContents();
          ui->table_can_logger->resizeRowsToContents();
          ui->table_can_logger->setSelectionBehavior(QAbstractItemView::SelectRows);
          ui->table_can_logger->verticalHeader()->setVisible(true);
          ui->table_can_logger->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeMode::Custom);
          ui->table_can_logger->verticalHeader()->setDefaultSectionSize(16);
          ui->table_can_logger->setShowGrid(false);
          ui->table_can_logger->setModel(model_can_logger);
      
      
          //Connection for auto scroll
          connect(model_can_logger, &QAbstractItemModel::rowsInserted, this, &ViewLogger::logger_table_rows_inserted);
          connect(model_can_logger, &QAbstractItemModel::rowsAboutToBeInserted, this,
                  &ViewLogger::logger_table_rows_to_be_inserted);
      

      Model slots in the view

      void
      ViewLogger::logger_table_rows_to_be_inserted() {
          QScrollBar* scrollbar = ui->table_can_logger->verticalScrollBar();
          do_scroll_table = scrollbar->value() == scrollbar->maximum();
      }
      void
      ViewLogger::logger_table_rows_inserted() {
          if (do_scroll_table) {
              QTimer::singleShot(50, ui->table_can_logger, &QTableView::scrollToBottom);
          }
      }
      

      My model append function, which adds new entry to the list, after it has been allocated with new:

      void
      CANLoggerDataModel::append(CANLoggerDataEntry* entry) {
          beginInsertRows(QModelIndex(), table_list.count(), table_list.count());
          table_list.append(entry);
          endInsertRows();
      }
      

      On every received message, I also have to check for some data, and for this reason I have a backward iterator in the model, too:

      void
      CANLoggerDataModel::canMsgSetSendAck(const ca_can_msg_ack_t* ack) {
          CANLoggerDataEntry* entry;
          QListIterator<CANLoggerDataEntry*> it(table_list);
          uint32_t len = table_list.count();
      
          it.toBack();
          while (it.hasPrevious() && len-- > 0) {
              entry = it.previous();
              if (entry->send_id == ack->uid) {
                  entry->status = static_cast<ca_status_t>(ack->status);
                  entry->message.time_sec = ack->time_sec;
                  entry->message.time_usec = ack->time_usec;
                  emit dataChanged(index(len, 0), index(len, columnCount() - 1));
                  break;
              }
          }
      }
      

      What could cause the lagging events? What could be optimized to improve this?

      Thanks

      M Offline
      M Offline
      mpergand
      wrote on last edited by
      #2

      @tilz0R
      Yeah, tableView/treeView are notoriously slow in this area.
      In a case similar to yours,
      https://forum.qt.io/post/551198

      I used a timer to update the view only a few times per second, not each time some data arrived:

      
          // constructeur
          DumpTreeModel(QTreeView* tree) : TreeItemModel(), _treeView(tree)
              {
              connect(this, &QAbstractItemModel::rowsInserted,this, &DumpTreeModel::rowsInserted);
      
           /** https://bugreports.qt.io/browse/QTBUG-61763
           *   QTreeView updates slow down with increasing delay if scrollToBottom is used
           */
              _timer.setInterval(200);
              _timer.start();
              connect(&_timer, &QTimer::timeout, [this] ()
                  {
                  static int count=0;
                  int rows=rowCount(QModelIndex());
      
                  if(count<rows AND _scrollToBottom)
                      _treeView->scrollToBottom();
      
                  count=rows;
                  });
      
              }
      
      

      Don't get me wrong, it doesn't solve the problem, it only postpone it.

      1 Reply Last reply
      2

      • Login

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved