I have an app that has a progress bar & spawns a worker thread to do some work & report back progress. The dialog class overrides the customEvent method so that I can process events that are being passed to the gui thread via the worker thread. Before I was using a QThread derived class as the worker thread and I changed it to use ACE_Thread_Manager->spawn() with a static function for the worker.
The problem shows up when I run the app and press the button so the worker is spawned & starts doing work. When it sends the signal to increment the progress bar I get the following errors logged to std out.
QPixmap: It is not safe to use pixmaps outside the GUI thread
This seems to happen when the progressBar->setValue() is called. So it seems like the setting of the progress bar is happening in a different thread than the main gui thread. I'm unclear as to how that's possible. I'm under the impression that I have a main gui thread which has my gui & the customEvent method is on that same thread and the worker is on it's own thread. Is this assumption wrong? And is there any difference when using the QThread derived class versus the static run_svc method?
Any help would be appreciated. The code snippets for the customEvent handler, run_svc, and button handler code are below and the code is attached.
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;
}
Button Handler Commented out lines where where I used a QT class derived from QThread. Using ACE has to spawn the thread has uncovered this issue.
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();
}