Return 从 C++ 到 QML 字符串的 GET 请求响应
Return response of GET request from c++ to QML string
我正在尝试执行一个简单的 GET 请求(使用修改后的用户代理),return 响应 QML 并执行 JSON 解析。
实际上它只有 return 加载完成时的页面内容,但不会 return 到 QML。
抱歉这个菜鸟问题。我是这门语言的新手,正在努力学习它:)
这是我的代码:
Home.qml
function getRequest() {
[...]
console.log('Request...')
var jsonResult = JSON.parse(connectNet.connectUrl("http://myURL.com/index.php").toString())
lbOutput.text = jsonResult.predictions[0].description.toString()
}
}
connectnet.cpp
#include "connectnet.h"
#include "stdio.h"
#include <QDebug>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QNetworkAccessManager>
#include <QUrl>
connectNet::connectNet(QObject *parent) : QObject(parent)
{
}
void connectNet::connectUrl(QString url)
{
QNetworkAccessManager *manager = new QNetworkAccessManager();
QNetworkRequest request;
QNetworkReply *reply = NULL;
request.setUrl(QUrl(url));
request.setRawHeader( "User-Agent" , "FAKE USER AGENT HERE" );
reply = manager->get(request);
connect(manager, SIGNAL(finished(QNetworkReply*)), this,
SLOT(replyFinished(QNetworkReply*)));
}
QString connectNet::replyFinished(QNetworkReply *reply)
{
return reply->readAll();
}
appname.cpp
#ifdef QT_QML_DEBUG
#include <QtQuick>
#endif
#include <sailfishapp.h>
#include "connectnet.h"
int main(int argc, char *argv[])
{
//INIT SETTINGS
QGuiApplication *app = SailfishApp::application(argc, argv);
QQuickView *view = SailfishApp::createView();
connectNet ConnectNet;
view->rootContext()->setContextProperty("connectNet", &ConnectNet);
view->setSource(SailfishApp::pathTo("qml/APPNAME.qml"));
view->showFullScreen();
app->exec();
}
希望我已经很好地解释了我要找的东西。感谢您的帮助。
============================================= =======
编辑 2015 年 8 月 20 日:添加更新 connectnet.h
#ifndef CONNECTNET_H
#define CONNECTNET_H
#include <QObject>
#include <QNetworkReply>
#include <QDebug>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QNetworkAccessManager>
#include <QUrl>
class ConnectNet : public QObject
{
Q_OBJECT
QNetworkAccessManager m_manager;
public:
ConnectNet(QObject * parent = 0) : QObject(parent) {
connect(&m_manager, &QNetworkAccessManager::finished,
[this](QNetworkReply * reply) {
if (reply->error() == QNetworkReply::NoError)
emit replyAvailable(QString::fromUtf8(reply->readAll()));
});
}
signals:
void replyAvailable(const QString & reply);
public slots:
void sendRequest(const QString url) {
QNetworkRequest request;
request.setUrl(QUrl(url));
request.setRawHeader("User-Agent", "MyLittleAgent");
m_manager.get(request);
}
};
#endif // CONNECTNET_H
这部分代码给出了很多错误:((下面的截图)
connect(&m_manager, &QNetworkAccessManager::finished,
[this](QNetworkReply * reply) {
if (reply->error() == QNetworkReply::NoError)
emit replyAvailable(QString::fromUtf8(reply->readAll()));
});
你的问题是思维同步。 connectUrl
不能 return 一个值(它确实没有),因为当它运行时结果不可用。相反,您必须做的是让 ConnectNet
class 在数据可用时发出信号。
如果您尝试制作一个执行 return 值的同步包装器,那将是一个可怕的想法:只要接收到结果,QML 引擎就会卡住。您可以通过在适当的时候拔出网络电缆来冻结您的应用程序,或者如果服务器已关闭。用户讨厌它,这是一个可怕的反模式,必须及时消除和劝阻。
这是您的 ConnectNet
(请不要 connectNet
,会员的小写名称!)class 的样子。请注意,QNetworkAccessManager
实例不需要是指针。
class ConnectNet : public QObject {
Q_OBJECT
QNetworkAccessManager m_manager;
public:
ConnectNet(QObject * parent = 0) : QObject(parent) {
connect(&m_manager, &QNetworkAccessManager::finished,
[this](QNetworkReply * reply) {
if (reply->error() == QNetworkReply::NoError)
emit replyAvailable(QString::fromUtf8(reply->readAll()));
});
}
Q_SLOT void sendRequest(const QString & url) {
auto request = QNetworkRequest(QUrl(url));
request.setRawHeader("User-Agent", "MyLittleAgent");
m_manager.get(request);
}
Q_SIGNAL void replyAvailable(const QString & reply);
};
由于 connectNet
实例实例在全局 QML 上下文中公开为 属性,您可以按如下方式连接到其信号:
function getRequest() {
connectNet.sendRequest("http://myURL.com/index.php")
}
function resultHandler(result) {
var jsonResult = JSON.parse(result.toString())
lbOutput.text = jsonResult.predictions[0].description.toString()
}
Rectangle { // or any other item
Component.onCompleted: {
connectNet.replyAvailable.connect(resultHandler)
}
...
}
我正在尝试执行一个简单的 GET 请求(使用修改后的用户代理),return 响应 QML 并执行 JSON 解析。
实际上它只有 return 加载完成时的页面内容,但不会 return 到 QML。
抱歉这个菜鸟问题。我是这门语言的新手,正在努力学习它:)
这是我的代码:
Home.qml
function getRequest() {
[...]
console.log('Request...')
var jsonResult = JSON.parse(connectNet.connectUrl("http://myURL.com/index.php").toString())
lbOutput.text = jsonResult.predictions[0].description.toString()
}
}
connectnet.cpp
#include "connectnet.h"
#include "stdio.h"
#include <QDebug>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QNetworkAccessManager>
#include <QUrl>
connectNet::connectNet(QObject *parent) : QObject(parent)
{
}
void connectNet::connectUrl(QString url)
{
QNetworkAccessManager *manager = new QNetworkAccessManager();
QNetworkRequest request;
QNetworkReply *reply = NULL;
request.setUrl(QUrl(url));
request.setRawHeader( "User-Agent" , "FAKE USER AGENT HERE" );
reply = manager->get(request);
connect(manager, SIGNAL(finished(QNetworkReply*)), this,
SLOT(replyFinished(QNetworkReply*)));
}
QString connectNet::replyFinished(QNetworkReply *reply)
{
return reply->readAll();
}
appname.cpp
#ifdef QT_QML_DEBUG
#include <QtQuick>
#endif
#include <sailfishapp.h>
#include "connectnet.h"
int main(int argc, char *argv[])
{
//INIT SETTINGS
QGuiApplication *app = SailfishApp::application(argc, argv);
QQuickView *view = SailfishApp::createView();
connectNet ConnectNet;
view->rootContext()->setContextProperty("connectNet", &ConnectNet);
view->setSource(SailfishApp::pathTo("qml/APPNAME.qml"));
view->showFullScreen();
app->exec();
}
希望我已经很好地解释了我要找的东西。感谢您的帮助。
============================================= =======
编辑 2015 年 8 月 20 日:添加更新 connectnet.h
#ifndef CONNECTNET_H
#define CONNECTNET_H
#include <QObject>
#include <QNetworkReply>
#include <QDebug>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QNetworkAccessManager>
#include <QUrl>
class ConnectNet : public QObject
{
Q_OBJECT
QNetworkAccessManager m_manager;
public:
ConnectNet(QObject * parent = 0) : QObject(parent) {
connect(&m_manager, &QNetworkAccessManager::finished,
[this](QNetworkReply * reply) {
if (reply->error() == QNetworkReply::NoError)
emit replyAvailable(QString::fromUtf8(reply->readAll()));
});
}
signals:
void replyAvailable(const QString & reply);
public slots:
void sendRequest(const QString url) {
QNetworkRequest request;
request.setUrl(QUrl(url));
request.setRawHeader("User-Agent", "MyLittleAgent");
m_manager.get(request);
}
};
#endif // CONNECTNET_H
这部分代码给出了很多错误:((下面的截图)
connect(&m_manager, &QNetworkAccessManager::finished,
[this](QNetworkReply * reply) {
if (reply->error() == QNetworkReply::NoError)
emit replyAvailable(QString::fromUtf8(reply->readAll()));
});
你的问题是思维同步。 connectUrl
不能 return 一个值(它确实没有),因为当它运行时结果不可用。相反,您必须做的是让 ConnectNet
class 在数据可用时发出信号。
如果您尝试制作一个执行 return 值的同步包装器,那将是一个可怕的想法:只要接收到结果,QML 引擎就会卡住。您可以通过在适当的时候拔出网络电缆来冻结您的应用程序,或者如果服务器已关闭。用户讨厌它,这是一个可怕的反模式,必须及时消除和劝阻。
这是您的 ConnectNet
(请不要 connectNet
,会员的小写名称!)class 的样子。请注意,QNetworkAccessManager
实例不需要是指针。
class ConnectNet : public QObject {
Q_OBJECT
QNetworkAccessManager m_manager;
public:
ConnectNet(QObject * parent = 0) : QObject(parent) {
connect(&m_manager, &QNetworkAccessManager::finished,
[this](QNetworkReply * reply) {
if (reply->error() == QNetworkReply::NoError)
emit replyAvailable(QString::fromUtf8(reply->readAll()));
});
}
Q_SLOT void sendRequest(const QString & url) {
auto request = QNetworkRequest(QUrl(url));
request.setRawHeader("User-Agent", "MyLittleAgent");
m_manager.get(request);
}
Q_SIGNAL void replyAvailable(const QString & reply);
};
由于 connectNet
实例实例在全局 QML 上下文中公开为 属性,您可以按如下方式连接到其信号:
function getRequest() {
connectNet.sendRequest("http://myURL.com/index.php")
}
function resultHandler(result) {
var jsonResult = JSON.parse(result.toString())
lbOutput.text = jsonResult.predictions[0].description.toString()
}
Rectangle { // or any other item
Component.onCompleted: {
connectNet.replyAvailable.connect(resultHandler)
}
...
}