[Solved] Asynchronous QQuickImageProvider with a timeout
-
Hi,
I can't seem to figure out how to set a timer with an asynchronous ImageProvider. The first thing I tried was
@
QImage MyImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
{
QTimer::singleShot(100,this,SLOT(myTimeout()));
...
doImageProviderThings();
...
return image;
}
@where myTimeout() is a slot with some implementation in MyImageProvider. Unfortunately QTimer was not able to interrupt the thread and myTimeout() executed when requestImage() returned.
Next I tried making QTimer* m_timer a member of MyImageProvider and connecting it to some signals in the MyImageProvider constructor:
@
MyImageProvider::MyImageProvider(QQuickImageProvider::ImageType type) :
QObject(0),
QQuickImageProvider(type, QQuickImageProvider::ForceAsynchronousImageLoading)
{
m_timer = new QTimer(this);
m_timer->setInterval(100);
m_timer->setSingleShot(true);
connect(m_timer,SIGNAL(timeout()),this,SLOT(myTimeout()));
connect(this, SIGNAL(finished()),m_timer,SLOT(stop()));
connect(this, SIGNAL(started()), m_timer, SLOT(start()));
}QImage MyImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
{
emit started();
...
doImageProviderThings();
...
emit finished();
return image;
}
@but as far as I can tell m_timer is never even started (the signals connected in the constructor are never detected).
Lastly, I tried setting up the connections in requestImage, but the program crashed when it got the the connect() statement:
@
MyImageProvider::FilmImageProvider(QQuickImageProvider::ImageType type) :
QObject(0),
QQuickImageProvider(type, QQuickImageProvider::ForceAsynchronousImageLoading)
{
m_timer = new QTimer(this);
m_timer->setInterval(100);
m_timer->setSingleShot(true);
}QImage MyImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
{
connect(m_timer,SIGNAL(timeout()),this,SLOT(myTimeout()));
connect(this, SIGNAL(finished()),m_timer,SLOT(stop()));
connect(this, SIGNAL(started()), m_timer, SLOT(start()));
emit started();
...
doImageProviderThings();
...
emit finished();
return image;
}
@I'm out of ideas. Any help would be greatly appreciated!
-
For your first attempt: You might have to check for events, either by calling qApp->processEvents(); in doImageProviderThings or by starting an event loop. (http://qt-project.org/doc/qt-5.0/qtcore/timers.html)
-
Okay thanks! But you think you could expand on how I could start an event loop? My confusion lies in the fact that I am already on a separate thread of execution and I'm able to send and receive signals to/from QML.
-
It depends on how you doImageProviderThings function looks. If there's a loop that run until the timeout you could just call qApp->processEvents() in the loop, if there's a place you're just waiting you could create a QEventLoop and call it's exec method, just remember to have some way to exit the loop too. Make sure to check the link, it tells you quite a bit about timers, threads and event loops.
-
Ah I see. Thanks so much for your help!