正确的解决方案是按照 @folibis 的指示创建 QQuickImageProvider 。但是,由于我使用的是Qt5.5,所以我无法制作QQuickAsyncImageProvider(这是在Qt5.6中引入的)。相反,您必须在构造 QQuickImageProvider 时将 Flags 设置为 QQmlImageProviderBase::ForceAsynchronousImageLoading。该标志确保调用 requestImage 不会阻塞主 GUI 线程。
但是,requestImage 期望返回图像,从而导致在不阻塞该线程的情况下从网络获取图像数据的挑战。 QNetworkAccessManager 通过信号返回其状态,而 QQuickImageProvider 不是 QObject,因此我创建了一个辅助类来监视 QNetworkReply 的信号。
class ReplyMonitor : public QObject
{
Q_OBJECT
public:
ReplyMonitor(QNetworkAccessManager *);
public Q_SLOTS:
void handleReplyFinished();
void handleSslErrors(QNetworkReply *, const QList<QSslError> &);
void handleAuthenticationRequired(QNetworkReply *, QAuthenticator *);
public:
bool finished;
};
and
ReplyMonitor::ReplyMonitor(QNetworkAccessManager *mgr)
: finished(false)
{
connect(mgr, SIGNAL( finished(QNetworkReply *) ), this, SLOT( handleReplyFinished() ));
connect(mgr, SIGNAL( sslErrors(QNetworkReply *, const QList<QSslError> &) ),
this, SLOT( handleSslErrors(QNetworkReply*, const QList<QSslError> &) ));
connect(mgr, SIGNAL( authenticationRequired(QNetworkReply *, QAuthenticator *) ),
this, SLOT( handleAuthenticationRequired(QNetworkReply*, QAuthenticator*) ));
}
void ReplyMonitor::handleReplyFinished()
{
finished = true;
}
Then in requestImage()
我检查finished
并打电话
while (!monitor->finished)
{
QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
}
在我创建要返回的图像之前
if (reply->error() == QNetworkReply::NoError)
{
image.loadFromData(reply->readAll());
}
我省略了创建 QNetworkRequest 的细节,因为这是有详细记录的。