[英]How to paint sequential image in efficient way in QQuickPaintedItem
出於某種原因,我需要在一個將在Qt Quick中使用的類中包含opencv VideoCapture。
有兩個類,一個是Camera,另一個是CameraView。 CameraView繼承自QQuickPaintedItem。
Camera類將定期獲取圖像。 它通過QObject :: startTimer(int interval)實現。 (例如,如果網絡攝像頭的fps為30,則定時器間隔為1000 / 30-8,8是時間偏差)。 一旦Camera獲得圖像,它會通過調用CameraView :: Update()通知CameraView重繪。
在CameraView :: paint(QPainter *)中,CameraView將從Camera類獲取圖像副本,並通過調用QPainter :: drawImage(...)繪制此圖像。
我在編碼過程中遇到了一些問題:
我嘗試用QThread替換時間事件以定期從相機獲取圖像。 當我在QThread中調用CameraView :: Update()時,CameraView不會重新繪制。 問題是什么?
在我的筆記本電腦中,當我使CameraView全屏繪制圖像時,我發現一個python程序變慢了。 是另一種以更低的成本和效率來繪制圖像的方法嗎?
如何基於QQuickPaintedItem C ++類有效地更新QML項目? 我將一些預處理委托給專用線程而不是UI線程上的計時器,它不再更新QML UI中的圖像。
從Qt中的UI線程觸發UI更新是強制性的,包括QML。 使CameraView暴露公共插槽updateImage
。
class CameraView : public QQuickPaintedItem
{
Q_OBJECT
Q_DISABLE_COPY(CameraView)
public:
CameraView(QQuickItem* parent = nullptr);
public slots:
void updateImage(const QImage&);
protected:
QImage m_image;
};
CameraView應該實現updateImage
並paint
如下:
void CameraView::updateImage(const QImage& image)
{
m_imageThumb = image; // does shallow copy of image data
update(); // triggers actual update
}
void CameraView::paint(QPainter* painter)
{
painter->drawImage(this->boundingRect(), m_image);
}
類OpenCvOnWorkerThread
應該啟動它的工作線程並公開signalUiUpdate:
OpenCvOnWorkerThread::OpenCvOnWorkerThread()
{
this->moveToThread(&m_workerThread);
// the below will allow communication between threads
connect(this, SIGNAL(signalUiUpdate(QImage)), m_cameraView, SLOT(updateImage(QImage)));
m_workerThread.start();
}
void OpenCvOnWorkerThread::cvRead()
{
QImage image;
// OpenCV details available in your code
// cv::read
// make QImage from frame
// deliver QImage to another thread
emit signalUiUpdate(image);
}
更新:在我自己的代碼中,來自“相機”線程的類似QML輸出我也會在無法處理視頻幀時處理UI線程停頓,以便信號發送者知道何時不發布視頻幀。 但這值得另一個問題。 或者這整個例子可以重新實現,沒有信號和槽,但有條件變量。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.