You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

QAbstractTableModel与QTableView频繁数据更新性能问题咨询

Qt表格视图实时更新性能问题求助

更新说明

该问题仅出现在debug(调试)版本中。相同条件下,release(发布)版本性能提升5-10倍,耗时10-20ms,而调试版本耗时100-150ms。需研究QTableView在不同构建模式下性能差异巨大的原因。

场景背景

我开发的应用从CAN总线接收帧数据,在独立线程处理后,通过Qt::QueuedConnection向主线程发送信号(每块消息对应一个信号)。主线程更新表格模型后触发dataChanged()信号更新视图。当前测试为每500ms接收20-25条消息,仅表格视图可见时因重绘/更新导致UI卡顿。

简化测试示例

为减少变量影响,我创建了由500ms定时器触发的简单表格模型模拟消息接收:

简易表格模型代码

#include <QAbstractTableModel>

class SimpleTableModel : public QAbstractTableModel
{
    Q_OBJECT
public:
    explicit SimpleTableModel(QObject *parent = nullptr)
        : QAbstractTableModel{parent}
    {

    }

    void setRowCount(int rows)
    {
        beginResetModel();
        m_rows = std::max(rows, 0);
        endResetModel();
    }
    void setColumnCount(int columns)
    {
        beginResetModel();
        m_columns = std::max(columns, 0);
        endResetModel();
    }

    void triggerDataChanged()
    {
        emit dataChanged(index(0, 0), index(m_rows - 1, m_columns - 1));
    }

    int rowCount(const QModelIndex &parent = QModelIndex()) const override
    {
        return m_rows;
    }

    int columnCount(const QModelIndex &parent = QModelIndex()) const override
    {
        return m_columns;
    }

    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
    {
        if (!index.isValid())
            return {};

        if (Qt::DisplayRole == role)
            return QStringLiteral("(%1:%2)").arg(index.row() + 1).arg(index.column() + 1);

        return {};
    }
private:
    int m_rows{};
    int m_columns{};
};

主窗口代码

class MainWindow : public QMainWindow
{
public:
  MainWindow()
  {
      auto table = new QTableView(this);
      setCentralWidget(table);
  
      auto model = new SimpleTableModel(this);
      auto timer = new QTimer(this);
      connect(timer, &QTimer::timeout, this, [model](){ model->triggerDataChanged(); });
  
      table->setModel(model);
  
      model->setColumnCount(5);
      model->setRowCount(100);
  
      timer->start(500);
  }
};

事件耗时监控代码

我还在QApplication::notify中添加了日志:

class MyApplication : public QApplication
{
    QElapsedTimer t;
public:
    MyApplication(int& argc, char ** argv) : QApplication(argc, argv) { }
    virtual ~MyApplication() { }

    virtual bool notify(QObject* receiver, QEvent* event)
    {
        t.start();
        bool ret = QApplication::notify(receiver, event);

        if(t.elapsed() > 1)
            qDebug("Processing event type %d for object %s took %dms",
                   (int)event->type(), receiver->objectName().toLocal8Bit().data(),
                   (int)t.elapsed());
        return ret;
    }
};

int main(int argc, char *argv[])
{
    MyApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

测试日志

...
Processing event type 12 for object qt_scrollarea_viewport took 98ms
Processing event type 77 for object MainWindow took 99ms

Processing event type 12 for object qt_scrollarea_viewport took 97ms
Processing event type 77 for object MainWindow took 98ms

Processing event type 12 for object qt_scrollarea_viewport took 93ms
Processing event type 77 for object MainWindow took 94ms
...

问题

  1. 是否有人遇到过Qt应用中表格视图频繁更新时的类似性能问题?
  2. 若有,采用了哪些策略或优化方案来解决实时UI更新的相关难题?

内容的提问来源于stack exchange,提问作者SVcpp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 12:56:08