現象:Tab1 放 QLabel,Tab2 放 QVideoWidget。換 QLabel 圖片後不刷新,切換 Tab 或拖動窗口邊緣才刷新。原因:QVideoWidget 佔用視頻繪製管線,阻塞主線程事件循環,導致 `update()`/`repaint()` 排隊延遲。
快速修復(三選一)
- 強制處理事件隊列:
`label->setPixmap(pixmap); QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);`
- 延遲到下一輪事件循環:
`QTimer::singleShot(0, [label, pixmap](){ label->setPixmap(pixmap); });`
- 將視頻播放移至獨立線程(根治):
用 `QMediaPlayer` + `QVideoSink`(Qt6)或 `QThread` 解碼,主線程只負責 UI。
排查步驟
- 註釋掉 Tab2 的 QVideoWidget → 正常 → 確認是視頻組件阻塞。
- 檢查 `QVideoWidget` 是否啟用了 `setAttribute(Qt::WA_PaintOnScreen)` 或 `setAttribute(Qt::WA_OpaquePaintEvent)` 導致繪製衝突。
- 嘗試 `label->update(); label->repaint(); QCoreApplication::sendPostedEvents();` 組合拳。
最佳實踐
視頻播放**必須**在獨立線程/進程,UI 線程僅接收幀並 `QLabel::setPixmap`/`QOpenGLWidget` 渲染。Qt6 推薦 `QMediaPlayer` + `QVideoSink` + `QVideoWidget`(硬件加速),彻底避開主線程繪製阻塞。