从响应到XmlHttpRequest(REST)的QML中显示图像

时间:2016-04-25 23:28:23

标签: qt qml

我需要从REST API调用中获取jpeg图像。我使用XMLHttpRequest作为请求需要身份验证标头(即我不能创建一个Image并使用user:passwd @ url将源设置为URL)。

我以为我能够使用Canvas并通过将REST数据设置为CanvasImageData对象来调用drawImage。但是,它不会绘制任何内容,也不会产生错误。 REST调用返回Content-Type:image / jpeg和Transfer-Encoding:chunked。

这种方法是否有效,或者我是否遗漏了其他内容?还有更好的建议吗?

// map_request.imageBytes is a property that holds the binary response from the REST query
Canvas {
id: location_map
width: 2400
height: 1500
contextType: '2d'

onPaint: {
  if (context && map_request.imageBytes)
  {
    var cid = context.createImageData(width, height);
    cid.data = map_request.imageBytes;
    context.drawImage(cid, 0, 0);
  }
}

1 个答案:

答案 0 :(得分:1)

正确的解决方案是在@folibis指示的情况下创建一个QQuickImageProvider。但是,由于我使用的是Qt5.5,我无法创建一个QQuickAsyncImageProvider(在Qt5.6中引入)。相反,在构建QQuickImageProvider到QQmlImageProviderBase :: ForceAsynchronousImageLoading时,必须设置Flags。此标志确保调用requestImage不会阻止主GUI线程。

但是,requestImage期望返回Image,从而导致挑战从网络获取Image数据而不阻塞该线程。 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);
  }

在我创建Image以返回

之前
  if (reply->error() == QNetworkReply::NoError)
  {
    image.loadFromData(reply->readAll());
  }

我省略了创建QNetworkRequest的详细信息,因为这是详细记录的。