← 返回列表

Qt 多线程下的 UI 刷新与数据解耦

2026-09-15 · Qt

采集线程每秒产生上千条数据,直接往 UI 发信号会让主线程卡死。三种方案我们全试过。

方案一:直接跨线程信号

最简单,但每条数据一个信号,事件循环直接被淹没。1000 条/秒时界面响应延迟超过 300ms。

方案二:批量投递

采集线程本地累积 50ms 的数据,一次性发出去。信号数量降到 20 次/秒:

void Collector::flush() {
    QVector<Sample> batch;
    batch.swap(buffer_);
    emit batchReady(batch);   // 队列连接,自动跨线程
}

界面流畅了,但有个坑:QVector 跨线程传递要注册元类型,否则队列连接会静默失败。

方案三:共享缓冲区 + 定时拉取

最终采用这个。采集线程写入环形缓冲,UI 用 QTimer 每 33ms 主动拉取一次:

代价是延迟增加最多 33ms,对测试场景完全可接受。