[英]Using Custom Events in QT4
我有一個應用程序,它有一個進度條並產生一個工作線程來做一些工作並報告進度。 對話框類重寫了customEvent方法,以便我可以處理通過工作線程傳遞給gui線程的事件。 在我使用QThread派生類作為工作線程之前,我將其更改為使用帶有靜態函數的ACE_Thread_Manager-> spawn()。
當我運行應用程序並按下按鈕以便工作人員產生並開始工作時,問題就出現了。 當它發送信號以遞增進度條時,我將以下錯誤記錄到std out。
QPixmap:在GUI線程之外使用pixmaps是不安全的
這似乎發生在調用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;
}
按鈕處理程序注釋掉我使用從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();
}
嘗試調用QApplication :: postEvent(...)而不是QApplication :: sendEvent()。 文檔說sendEvent直接發送事件,這意味着它直接從另一個線程調用customEvent()函數。 postEvent()將事件添加到事件隊列中,稍后可以通過主GUI事件循環將事件調度到customEvent()。
僅僅因為customEvent()函數是在主GUI線程中創建的對象的成員並不意味着另一個線程無法調用該函數。 我相信當你從另一個線程調用QApplication :: sendEvent()時會發生這種情況。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.