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 ...
问题
- 是否有人遇到过Qt应用中表格视图频繁更新时的类似性能问题?
- 若有,采用了哪些策略或优化方案来解决实时UI更新的相关难题?
内容的提问来源于stack exchange,提问作者SVcpp
相关产品推荐
相关产品推荐

