我正在使用QtConcurrent做一些沉重的背景圖像處理,我想顯示圖像,而其中的一部分正在逐步更新。 圖像的每一行分別計算並傳遞一個函子。Qt併發映射和進度報告
爲了計算整個圖像然後我有項的序列,我傳遞給QtConcurrent映射,並且每個線發射的信號時,它完成計算
下面是類工人的實例化:
//living in the main(gui) thread !
Worker::Worker(VideoEngine* engine):_engine(engine){
_watcher = new QFutureWatcher<bool>;
_watcher->setPendingResultsLimit(200);
connect(_watcher, SIGNAL(resultReadyAt(int)), this, SLOT(onProgressUpdate(int)));
connect(_watcher, SIGNAL(finished()), engine, SLOT(engineLoop()));
}
下面是報告進度插槽:
void Worker::onProgressUpdate(int i){
if(i < (int)_rows.size() && i%10==0){
cout << " index = " << i << " y = "<< _rows[i] << endl;
_engine->checkAndDisplayProgress(_rows[i],i);
}
}
現在用法:
void Worker::_computeTreeForFrame(.../*unrelevant args*/){
....
....
_watcher->setFuture(
QtConcurrent::mapped(_sequence,
boost::bind(&VideoEngine::metaEnginePerRow,_1,output)));
}
}
所有的信號都被髮射出去,但是隻有當Qtconcurrent :: mapped與序列中的所有項目完成時纔會調用onProgressUpdate插槽。
當執行它時,序列正在處理時有很大的延遲,然後所有的插槽都會在後面順序執行。
我試過所有類型的信號/插槽連接,並沒有一個改變了這種行爲。
任何線索?
++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++++ 編輯後shf建議 +++++ ++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++
此調用是在主(gui)線程中完成的。 我改變了呼籲:
_computeFrameWatcher->setFuture(QtConcurrent::run(_worker,&Worker::computeTreeForFrame));
由於_computeTreeForFrame
現在在另一個線程中執行的,我改變了調用QtConcurrent ::映射到:
_watcher->setFuture(QtConcurrent::mapped(_sequence,
boost::bind(&VideoEngine::metaEnginePerRow,_1,output)));
_watcher->waitForFinished();
這將導致完全行爲之前相同。
++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++++馬立克ř建議 後 EDIT ++++ ++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++
好吧,所以我做了這樣的測試,這裏是我觀察到的:
QtConcurrent ::地圖:
- 不發出信號
resultReadyAt(int)
QtConcurrent ::映射
- 發出
resultReadyAt(int)
完成
如果對地圖功能的調用在一個單獨的線程完成相同的步驟不要緊,只有當行爲遭遇。
我也給一試的信號progressValueChanged(int)
作爲Qt的progressDialog例子說明。 信號progressValueChanged(int)
得到僅射出的2行在圖像中(第一個和最後)。 這真的很奇怪,因爲在Qt進度對話框中它會順利發送。
我改了一下Qt的例子推出地圖功能在另一個線程比主線程,它仍然運作良好在這種情況下。
的問題,必須從其他地方出現。
也許GUI事件循環做一些我不奢望?我不知道什麼。
我現在將嘗試QtConcurrent :: mappedReduced並與結果:-)
報告++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++給人一種嘗試QtConcurrent後 編輯:: mappedReduced +++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++
它不工作,並呼籲只有當「地圖」功能完成的「降低」功能。換句話說,它與之前的信號/插槽機制相同。
我低的可能性現在
運行++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++ + 編輯我回來了一個解決方案儘可能接近Qt的進度對話框例如 +++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++ ++++如果我不能得到比Qt的例子相同的行爲
一定出事了。
下面是現在的代碼:
//created in the main thread! (gui)
Worker::Worker(VideoEngine* engine):_engine(engine),_watcher(0){
_watcher = new QFutureWatcher<void>;
_watcher->setPendingResultsLimit(200);
connect(_watcher,SIGNAL(progressValueChanged(int)), _engine,
SLOT(onProgressUpdate(int)));
connect(_watcher, SIGNAL(finished()), engine, SLOT(engineLoop()));
}
//executed on the main thread
void Worker::computeTreeForFrame(...){
...
_watcher->setFuture(QtConcurrent::map(_sequence,boost::bind(metaEnginePerRow,_1,output)));
...
}
到computeTreeForFrame的電話...
...
_worker->computeTreeForFrame();
...
此通話插槽完成。
它發出線0和最後一行的信號,如前所述,但不發出任何其他信號。
不應該這樣做是完全的Qt例子嗎?
您的問題描述不完整。這很難幫助,但我會嘗試。 –
怎麼這樣?你可以說得更詳細點嗎 ?你想要什麼信息? – Lex
編輯答案。 – Shf