У меня есть приложение, которое имеет индикатор выполнения и порождает рабочий поток, чтобы выполнить некоторую работу и сообщить о прогрессе. Класс диалога переопределяет метод customEvent, так что я могу обрабатывать события, которые передаются в поток графического интерфейса через рабочий поток. До того, как я использовал производный класс QThread в качестве рабочего потока, я изменил его на использование ACE_Thread_Manager-> spawn () со статической функцией для рабочего.
Проблема появляется, когда я запускаю приложение и нажимаю кнопку, чтобы рабочий порождался и начинал делать работу. Когда он посылает сигнал для увеличения индикатора выполнения, я получаю следующие ошибки, записываемые в стандартный вывод.
QPixmap: использование пиксельных карт вне потока GUI небезопасно
Это, кажется, происходит, когда вызывается progressBar-> setValue (). Таким образом, кажется, что настройка индикатора выполнения происходит в другом потоке, чем основной поток графического интерфейса. Мне неясно, как это возможно. У меня сложилось впечатление, что у меня есть основной поток графического интерфейса с моим графическим интерфейсом, а метод customEvent находится в том же потоке, а рабочий находится в собственном потоке. Это предположение неверно? И есть ли разница при использовании производного класса 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;
}
обработчик кнопок
Закомментированы строки, где я использовал класс QT, производный от QThread. Использование 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();
}