我有一個應用程序,它有一個進度條&產生一個工作線程做一些工作&報告返回進度。對話框類重寫了customEvent方法,以便我可以處理通過工作線程傳遞給gui線程的事件。在我使用QThread派生類作爲工作者線程之前,我將它改爲使用ACE_Thread_Manager-> spawn()以及工作者的靜態函數。在QT4中使用自定義事件
當我運行該應用程序並按下按鈕時,問題就會顯示出來,因此工作人員開始生成&開始工作。當它發送信號來遞增進度條時,我得到以下錯誤記錄到標準輸出。
的QPixmap:這是不是安全使用GUI線程
這似乎當progressBar->的setValue()被調用發生之外的像素映射。所以看起來進度條的設置發生在與主gui線程不同的線程中。我不清楚這是可能的。我的印象是,我有一個主要的gui線程,它有我的gui & customEvent方法在同一個線程上,而worker在它自己的線程上。這個假設是錯誤的嗎?使用QThread派生類與靜態run_svc方法有什麼不同嗎?
任何幫助,將不勝感激。 customEvent處理程序,run_svc和按鈕處理程序代碼的代碼片段位於下方,代碼已附加。
void MyDlgEx::customEvent(QEvent * e)
{
if (e->type() == IdNumOperations)
{
NumOperations* pEvt = static_cast<NumOperations*>(e);
_steps = 0;
cout << "Num Operations = " << pEvt->operations() << endl;
}
else if (e->type() == IdStep)
{
if (_steps % 10 == 0)
{
cout << "Step++ = " << _steps << endl;
}
_steps++;
_progressBar->setValue(_steps);
}
}
void* MyDlgEx::run_svc(void* args)
{
auto_ptr<ThreadArgs> thread_args(static_cast<ThreadArgs*>(args));
QApplication::sendEvent((QObject*)thread_args->m_pDlg, new NumOperations(300));
// does some work that takes time -- ommitted for clarity
// called in a loop
QApplication::sendEvent((QObject*)thread_args->m_pDlg, new Step());
QApplication::sendEvent((QObject*)thread_args->m_pDlg, new Completed());
return 0;
}
按鈕處理 註釋掉其中其中I用於從QThread的派生的QT班線。使用ACE必須產生線程才能發現此問題。
void MyDlgEx::btnShowProgress_clicked()
{
//_pProc = new ProcessThread(this);
//_pProc->run();
auto_ptr<ThreadArgs> thread_args(new ThreadArgs(this));
if (ACE_Thread_Manager::instance()->spawn(
MyDlgEx::run_svc,
static_cast<void*>(thread_args.get()),
THR_DETACHED | THR_SCOPE_SYSTEM) == -1)
cout << "Failed to spawn thread." << endl;
thread_args.release();
}
是的,更改爲postEvent工作。我將不得不做一些更多的測試,並打印出線程ID以便更好地理解發生了什麼。我習慣了SendMessage&PostMessage在WIN32 api中的SendMessage等待,直到處理程序完成,因爲PostMessage只是發送消息並返回。 WIN32 Post&Send消息是否與QT相同或略有不同? 感謝您的回覆。這是一個不錯的聖誕禮物:) – 2009-12-25 17:13:25
我不熟悉WIN32 API,但對我來說聽起來是一樣的。 sendEvent塊,因爲它直接調用事件處理程序,但在將事件推入隊列後postEvent將返回,並且如果從GUI線程調用postEvent,則該事件稍後將由另一個線程或同一個線程處理。我懷疑(但不知道)Qt和WIN32版本之間存在細微的差異,但是它聽起來像是它們在主要觀點上是相似的。 你看過使用Qt信號和插槽而不是自定義事件嗎?他們可能會讓事情變得更簡單,更清潔。 – 2009-12-26 16:37:55