[英]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.