2016-12-19 12 views
0

Я пытаюсь построить клиент для веб-службы. Моя цель - отправить запрос на мой сервер каждую секунду. Я использовал эту библиотеку, чтобы помочь мне: QHttpPass QCoreApplication в параметре

создать таймер, который я связываю с сигналом на мой QCoreApplication app и отправить мой запрос, когда досягаемость таймера 1 второго.

Вот как я это делаю:

main.cpp

#include "request.h" 

int main(int argc, char** argv) { 

    QCoreApplication app(argc, argv); 
    Request* request = new Request(); 
    request->sendRequestPeriodically(1000, app); 


    return app.exec(); 
} 

request.h

//lots of include before 
class Request 
{ 
    Q_OBJECT 

public: 
    Request(); 
    void sendRequestPeriodically (int time, QCoreApplication app); 

public slots: 
    void sendRequest (QCoreApplication app); 

}; 

request.cpp

#include "request.h" 

void Request::sendRequest (QCoreApplication app){ 
    using namespace qhttp::client; 
    QHttpClient client(&app); 
    QUrl  server("http://127.0.0.1:8080/?Clearance"); 

    client.request(qhttp::EHTTP_GET, server, [](QHttpResponse* res) { 
     // response handler, called when the incoming HTTP headers are ready 


     // gather HTTP response data (HTTP body) 
     res->collectData(); 

     // when all data in HTTP response have been read: 
     res->onEnd([res]() { 
      // print the XML body of the response 
      qDebug("\nreceived %d bytes of http body:\n%s\n", 
        res->collectedData().size(), 
        res->collectedData().constData() 
       ); 

      // done! now quit the application 
      //qApp->quit(); 
     }); 

    }); 

    // set a timeout for the http connection 
    client.setConnectingTimeOut(10000, []{ 
     qDebug("connecting to HTTP server timed out!"); 
     qApp->quit(); 
    }); 
} 

void Request::sendRequestPeriodically(int time, QCoreApplication app){ 
    QTimer *timer = new QTimer(this); 
    QObject::connect(timer, SIGNAL(timeout()), this, SLOT(sendRequest(app))); 
    timer->start(time); //time specified in ms 
} 

Request::Request() 
{ 

} 

Я получил эти ошибки:

C:\Qt\5.7\mingw53_32\include\QtCore\qcoreapplication.h:211: erreur : 'QCoreApplication::QCoreApplication(const QCoreApplication&)' is private 
    Q_DISABLE_COPY(QCoreApplication) 

C:\Users\ebelloei\Documents\qhttp\example\client-aircraft\main.cpp:7: erreur : use of deleted function 'QCoreApplication::QCoreApplication(const QCoreApplication&)' 

Я новичок в Qt, но я предполагаю, что это происходит от того, что я не могу PASSE мой QCoreApplication в параметрах, правильно ли это?

ответ

4

Прежде всего, если вам нужно получить доступ к экземпляру глобального приложения, вы не должны его передавать. Используйте макрос qApp, или QCoreApplication::instance().

Но это, кроме того, указывает: QHttpClient client экземпляр - это локальная переменная, ее время жизни управляется компилятором. Нет смысла давать родителям. client будет уничтожен сразу же, как sendRequest выходов: ваш sendRequest является фактически не-операцией из-за этого.

У вас также есть ошибки в ваших connect заявлений вы не можете передать значения аргументов, используя старый стиль connect синтаксис:

// Wrong: the connection fails and does nothing. 
connect(timer, SIGNAL(timeout()), this, SLOT(sendRequest(foo))); 
// Qt 5 
connect(timer, &QTimer::timeout, this, [=]{ sendRequest(foo); }); 
// Qt 4 
this->foo = foo; 
connect(timer, SIGNAL(timeout()), this, SLOT(sendRequest())); 
    // sendRequest would then use this->foo 

В идеале, вы должны перестроить свой код, чтобы использовать QNetworkAccessManager.Если нет, то вы должны держать QHttpClient экземпляр живой в main:

int main(int argc, char** argv) { 
    QCoreApplication app(argc, argv); 
    qhttp::client::QHttpClient client; 
    auto request = new Request(&client); 
    request->sendRequestPeriodically(1000); 
    return app.exec(); 
} 

А потом:

class Request : public QObject 
{ 
    Q_OBJECT 
    QTimer m_timer{this}; 
    qhttp::client::QHttpClient *m_client; 
public: 
    explicit Request(qhttp::client::QHttpClient *client); 
    void sendRequestPeriodically(int time); 
    void sendRequest(); 
}; 

Request::Request(qhttp::client::QHttpClient *client) : 
    QObject{client}, 
    m_client{client} 
{ 
    QObject::connect(&m_timer, &QTimer::timeout, this, &Request::sendRequest); 
} 

void Request::sendRequestPeriodically(int time) { 
    timer->start(time); 
} 

void Request::sendRequest() { 
    QUrl server("http://127.0.0.1:8080/?Clearance"); 

    m_client->request(qhttp::EHTTP_GET, server, [](QHttpResponse* res) { 
     ... 
    }); 
} 
+0

Очень сильный ответ и понимание моей проблемы. Я помню, что просил что-то 4 года назад здесь и получил от вас ответ, спасибо за вашу работу. –

1

Вы не можете передать экземпляр объекта QCoreApplication через свой конструктор копирования, вы должны передать указатель на QCoreApplication.

Все «приложение QCoreApplication» следует заменить на «приложение QCoreApplication *», и вызовы этих функций должны включать указатель на приложение, а не его копию.

request.h

//lots of include before 
class Request 
{ 
    Q_OBJECT 

public: 
    Request(); 
    void sendRequestPeriodically (int time, QCoreApplication *app); 

public slots: 
    void sendRequest (QCoreApplication *app); 

}; 

request.cpp

#include "request.h" 

void Request::sendRequest (QCoreApplication *app){ 
    using namespace qhttp::client; 
    QHttpClient client(app); 
    QUrl  server("http://127.0.0.1:8080/?Clearance"); 

    client.request(qhttp::EHTTP_GET, server, [](QHttpResponse* res) { 
     // response handler, called when the incoming HTTP headers are ready 


     // gather HTTP response data (HTTP body) 
     res->collectData(); 

     // when all data in HTTP response have been read: 
     res->onEnd([res]() { 
      // print the XML body of the response 
      qDebug("\nreceived %d bytes of http body:\n%s\n", 
        res->collectedData().size(), 
        res->collectedData().constData() 
       ); 

      // done! now quit the application 
      //qApp->quit(); 
     }); 

    }); 

    // set a timeout for the http connection 
    client.setConnectingTimeOut(10000, []{ 
     qDebug("connecting to HTTP server timed out!"); 
     qApp->quit(); 
    }); 
} 

void Request::sendRequestPeriodically(int time, QCoreApplication app){ 
    QTimer *timer = new QTimer(this); 
    QObject::connect(timer, SIGNAL(timeout()), this, SLOT(sendRequest(app))); 
    timer->start(time); //time specified in ms 
} 

Request::Request() 
{ 

} 

main.cpp

#include "request.h" 

int main(int argc, char** argv) { 

    QCoreApplication app(argc, argv); 
    Request* request = new Request(); 
    request->sendRequestPeriodically(1000, &app); 

    return app.exec(); 
} 

Редактировать Как сказал KubaOber, есть еще проблемы в вашем коде, прочитайте его ответ

+0

Это пропускает другие проблемы с кодом и не будет работать, как указано. –

+0

@KubaOber, пожалуйста, сделайте это более понятным? –

+0

@KubaOber Я ответил на его ошибку, вы правы там больше ошибок на коде –