【问题标题】:QIODevice::read: device not open Remote JSON File QTQIODevice::read: 设备未打开远程 JSON 文件 QT
【发布时间】:2017-11-18 02:03:00
【问题描述】:

这让我发疯了。一直在到处寻找解决方案,但令人惊讶的是,很少有关于将远程 JSON 文件加载到 QT 中。

我有这段代码,当我尝试加载本地文件时可以正常工作。

QFile jsonFile("/Users/blah/blah/myfile.json");


if (!jsonFile.open(QIODevice::ReadOnly | QIODevice::Text))
{
    qDebug() << "Unable to open file, exiting...";
    return;
}

QByteArray jsonData = jsonFile.readAll();
QJsonDocument doc = QJsonDocument::fromJson(jsonData);
QJsonObject jObject = doc.object();
QVariantMap json_map = jObject.toVariantMap();

QString getNow = json_map["now"].toString();
QString getImage = json_map["image"].toString();
QString getNext = json_map["next"].toString();

ui->live1->setText(getNow);
ui->live2->setText(getImage);
ui->live3->setText(getNext);

但我在过去 5 小时内尝试过的任何事情都无法让它加载远程文件,而且我找不到直接的解释来说明如何实现如此简单的事情。

 QFile jsonFile("https://myserver.com/myfile.json");
 QUrl jsonFile("https://myserver.com/myfile.json");

还有一大堆其他方法,包括 QTextStream 和我认为可能会这样做的任何其他方法,例如 this,这对于我正在尝试做的事情来说似乎太过分了。但一切要么返回......

 QIODevice::read: device not open

...或一系列其他错误让我知道我搞砸了。

有人能帮我摆脱困境吗?

** 编辑 **

使用 QNetwork 库,但现在在 QObject::connect 行上抛出 expected expression 错误?

 QNetworkAccessManager manager;
    QNetworkRequest request(QUrl("https://myserver.com/myfile.json"));
    QNetworkReply *reply = manager.get(request);

    QObject::connect(reply, &QNetworkReply::finished, [&]() {
        QByteArray data = reply->readAll();

        QJsonDocument doc = QJsonDocument::fromJson(data);
        QJsonObject jObject = doc.object();
        QVariantMap json_map = jObject.toVariantMap();

        QString getNow = json_map["now"].toString();
        QString getImage = json_map["image"].toString();
        QString getNext = json_map["next"].toString();

        ui->live1->setText(getNow);
        ui->live2->setText(getImage);
        ui->live3->setText(getNext);

        reply->deleteLater();
    });

** 编辑 2 **

我刚刚意识到我需要包含 C++11 编译器

 CONFIG += c++11

但现在它只是在精神上抛出 SSL 错误

 qt.network.ssl: QSslSocket: cannot resolve TLSv1_1_client_method
 qt.network.ssl: QSslSocket: cannot resolve TLSv1_2_client_method
 qt.network.ssl: QSslSocket: cannot resolve TLSv1_1_server_method
 qt.network.ssl: QSslSocket: cannot resolve TLSv1_2_server_method
 qt.network.ssl: QSslSocket: cannot resolve SSL_select_next_proto
 qt.network.ssl: QSslSocket: cannot resolve SSL_CTX_set_next_proto_select_cb
 qt.network.ssl: QSslSocket: cannot resolve SSL_get0_next_proto_negotiated

** 编辑 3 **

取得一些进展(我猜...)

QT 似乎使用的是旧版本的 SSL(根据文档可能不支持)。

当被问及 SSL 时,QDebug 吐出了这个...

 Support SSL:   true
 Lib Version Number:  9470431
 Lib Version String:  "OpenSSL 0.9.8zh 14 Jan 2016"
 Lib Build Version Number:  268439727
 Lib Build Version String:  "OpenSSL 1.0.1j 15 Oct 2014"

所以现在我需要弄清楚如何让 QT 使用我机器上的较新版本。

【问题讨论】:

  • 你需要 QtNetwork 来做这个。 QFile 无法打开远程 URL。
  • 哦,伙计.. 我希望 QT 文档对新手更友好一些。这应该是我在寻找这个时发现的第一件事,但你是我见过的第一个提到它的人。所以我想用 导入文件是一种完全不同的方法吗?
  • 是的,请在下面查看我的答案以获取一个简单的示例。
  • 是的,一切都完成了,QT 现在抱怨我的 SSL 版本太旧了?根据终端,我正在运行 OpenSSL 1.0.2l 25 May 2017,根据 QT 文档应该支持吗?
  • 谢谢,但这两个帖子都是针对 Windows 的,我是在 Mac 上构建的。

标签: c++ json qt qt5


【解决方案1】:

QFile 不支持远程 URI。为此,您需要使用 QtNetwork。

以下 C++11 示例演示如何从远程 URI 检索 JSON:

QNetworkAccessManager manager;
QNetworkRequest request(QUrl("http://example.com/file.json"));
QNetworkReply *reply = manager.get(request);

QObject::connect(reply, &QNetworkReply::finished, [&]() {
    QByteArray data = reply->readAll();
    // do stuff with data
    reply->deleteLater();
});

【讨论】:

  • 感谢 Nathan,因此我已将编辑添加到上面的帖子中,因为它太长了无法发表评论,但它在 QObject::connect 行上抛出了 expected expression 错误?对不起,如果我只是在这里很密集......
  • SSL 错误是由一个相当微妙的问题引起的。您需要安装 OpenSSL 库,因为 Qt 默认不提供它们(由于许可问题)。您需要的两个库是ssleay32.dll 和libeay32.dll。
  • 知道它们在 Mac 上的用途吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-02-26
  • 2020-07-13
  • 1970-01-01
  • 1970-01-01
  • 2015-10-27
  • 2017-05-28
  • 1970-01-01
相关资源
最近更新 更多