[英]QTimer in worker thread
我有一个Worker
类,它在另一个线程中做一些工作,使用moveToThread()
将其放置在其中。 在Worker::doWork()
方法内部,我还创建了一个QTimer
,该QTimer
应该根据任务所需的估计时间发出进度更新。
这是一个例子:
ThreadController::ThreadController()
{
Worker* worker = new Worker;
worker->moveToThread(&m_workerThread);
// ...
m_workerThread.start();
emit startWorker(params); // connected to Worker::doWork()
}
class Worker : public QObject
{
Q_OBJECT
public slots:
Worker::doWork(const QString& params)
{
QTimer* timer = new QTimer(this);
connect( timer, SIGNAL(timeout)), this, SLOT(updateProgress()) );
timer->start(estimateTaskLength() / 100);
// perform work...
}
}
现在,这无法按预期进行。 仅在工作完成后才开始调用updateProgress()
插槽。
当计时器到期时, timeout
事件将排队到工作线程QThread的事件队列中。 但是,您的工作者QThread忙于执行doWork()
,因此无法处理该事件。 一旦线程完成doWork
,控件将返回QThread的事件循环并执行timeout
事件。
解决此问题的最简单方法是在执行doWork()
过程中以一定间隔使用QCoreApplication::processEvents()
手动调用事件循环。 这将使QThread可以更早地执行timeout
事件。
或者,您可以使用其他线程来执行这些估计。 如果它们不太注重性能,那么您甚至可以使用GUI /主线程。 GUI /主线程应保持对事件的“响应”(否则应用程序似乎挂起),因此它可以及时处理timeout
事件。
这可能取决于Qtimer :: timeout和this :: updateProgress之间的连接类型。
默认情况下,它是Qt :: AutoConnection,这意味着超时信号将排队,直到接收对象准备好处理它为止。 即在doWork完成之后。
如果使用
connect( timer, SIGNAL(timeout)), this, SLOT(updateProgress()), Qt::DirectConnection );
超时信号应立即处理。 (但是请确保包括必要的互斥对象和填充,因为这是典型的情况,例如可能发生并发访问。)
( http://qt-project.org/doc/qt-4.8/qt.html#ConnectionType-enum )
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.