我有一个应用程序,它有一个进度条&产生一个工作线程做一些工作&报告返回进度。对话框类重写了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