正确的解决方案是创建一个QQuickImageProvider作为@folibis指示。但是,由于我使用Qt5.5,我无法创建一个QQuickAsyncImageProvider(在Qt5.6中引入)。相反,您必须在构建QQuickImageProvider时将标志设置为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;
};
和
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;
}
在
requestImage()
然后我检查finished
并调用
while (!monitor->finished)
{
QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
}
之前,我创建图像的
if (reply->error() == QNetworkReply::NoError)
{
image.loadFromData(reply->readAll());
}
我奥姆返回提供了创建QNetworkRequest的详细信息,因为这是详细记录的。
'cid.data'必须是RGBA顺序的图像像素数据,而不是原始图像数据。你能从服务器以base64编码的字符串接收图像吗?在这种情况下,您可以创建一个图像为'img.source ='data:image/png; base64,...编码的数据在这里...'。另一个解决方法是使用自定义图像提供程序。 – folibis
你知道,这应该是一个答案upvote @folibis :) – BaCaRoZzo
我怀疑我需要切换到自定义图像提供商,因为我无法获得base64编码的图像数据。感谢您澄清CanvasImageData的格式。请随时为我的问题创建一个答案,然后我会为您添加标记。 – Bargonaut