Slot wird bei CLI Programm getriggert

Alles rund um die Programmierung mit Qt
Antworten
MarcoG88
Beiträge: 5
Registriert: 12. April 2013 17:33

Slot wird bei CLI Programm getriggert

Beitrag von MarcoG88 »

Hallo,

Bin grad am verrückt werden. Ich habe eine GUI-Anwendung geschrieben mit welcher ich HTTP Network Requests abschicken kann. Alles funktioniert, auch mit Authentifzierung oder über einen Proxy. Wollte das ganze jetzt noch für die Kommandozeile machen damit man diese Requests auch aus dem Terminal ausführen kann, gleicher Code, jedoch passiert "gar nichts". Weder Fehlermeldung, Noch Meldungungen beim Compilern. Ich verstehe nicht wo das Problem hängt.

Hier der Code der CLI Anwendung:

Code: Alles auswählen

void Requestor::replyFinished(QNetworkReply * reply) {
    if (reply->error() == QNetworkReply::NoError) {
        cout << QString(reply->readAll()).toStdString() << endl;
    }
    else {
        int code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
        cout << reply->errorString().toStdString()  << endl;
        cout << "Errorcode: ";
        cout << code << endl;
        cout << QString(reply->readAll()).toStdString().c_str() << endl;
    }

    cout << "Finished :)" << endl;
}
void Requestor::sslErrorReceived(QNetworkReply*, QList<QSslError> errorlist) {
    foreach (QSslError se, errorlist) {
        cout << se.errorString().toStdString() << endl;
    }
}
void Requestor::authentificationRequired(QNetworkReply* reply, QAuthenticator*) {
    cout << "Authentification Required: " << reply->errorString().toStdString() << endl;

}
void Requestor::Request() {
    QNetworkAccessManager *manager = new QNetworkAccessManager(this);
    this->connect(manager, SIGNAL(finished(QNetworkReply*)),
            this, SLOT(replyFinished(QNetworkReply*)));
    this->connect(manager, SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),
                  this, SLOT(sslErrorReceived(QNetworkReply*, QList<QSslError>)));
    this->connect(manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)),
                  this, SLOT(authentificationRequired(QNetworkReply*, QAuthenticator*)));

    cout << "use proxy? (y/n):";
    string up;
    getline(cin, up);
    QString useProxy = QString::fromStdString(up);

    if (useProxy.toLower() == "y") {
        QNetworkProxy proxy;

        cout << "Proxy Hostname:";
        string input;
        getline(cin, input);
        QString hostname = QString::fromStdString(input);

        cout << "Proxy port:";
        int port = cin.get();

        proxy.setHostName(hostname);
        proxy.setPort(port);

        cout << "Proxy user (leave empty for none)";
        getline(cin, input);
        QString usr = QString::fromStdString(input);

        if (usr != "") {
            proxy.setUser(usr);
        }

        cout << "Proxy Password (leave empty for none)";
        getline(cin, input);
        QString pwd = QString::fromStdString(input);

        if (pwd != "") {
            proxy.setPassword(pwd);
        }

        proxy.setType(QNetworkProxy::HttpProxy);
        QNetworkProxy::setApplicationProxy(proxy);
        manager->setProxy(proxy);
    }


    cout << "Request URL:";
    string input;
    getline(cin, input);
    QString url = QString::fromStdString(input);


    QUrl targetURL(url);

    cout << "Request User (leave empty for none):";
    getline(cin, input);
    QString httpusr = QString::fromStdString(input);

    targetURL.setUserName(httpusr);

    cout << "Request Password (leave empty for none):";
    getline(cin, input);
    QString httppwd = QString::fromStdString(input);

    targetURL.setPassword(httppwd);
    QNetworkRequest netreq(targetURL);
    cout << "Waiting until Request finished..." << endl;
    //netreq.setHeader(QNetworkRequest::ContentTypeHeader, "text/html");
    manager->get(netreq);
}

Und die Header:

Code: Alles auswählen

#ifndef REQUESTOR_H
#define REQUESTOR_H

#include <QObject>
#include <QtNetwork/QNetworkAccessManager>
#include <QSslError>
#include <QList>
#include <QUrl>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QNetworkProxy>
#include <iostream>
#include <string>
#include <QString>

using namespace std;

class Requestor : public QObject
{
    Q_OBJECT

private slots:
    void authentificationRequired(QNetworkReply*, QAuthenticator*);
    void sslErrorReceived(QNetworkReply*, QList<QSslError>);
    void replyFinished(QNetworkReply *);

public:
    Requestor();
    void Request();
};

#endif // REQUESTOR_H

Für mich sieht es so aus, als würde kein Signal ausgeführt werden, und somit auch kein Slot getriggert.... Auch mit Debugging habe ich das Problem noch nicht herausgefunden.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: Slot wird bei CLI Programm getriggert

Beitrag von Christian81 »

Ist denn eine QCoreApplication vorhanden und läuft die Eventloop?
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
MarcoG88
Beiträge: 5
Registriert: 12. April 2013 17:33

Re: Slot wird bei CLI Programm getriggert

Beitrag von MarcoG88 »

Hi Christian81,

ja eine QCoreApplication existiert in der main.cpp.
Aber eigentlich wird das e.exec nie erreicht weil sich der Code
in der endlos Schleife befindet... Mache ich das a.exec weiter nach oben vor die schleife
wird das Programm nicht fortgesetzt :-/

Code: Alles auswählen

    
QCoreApplication a(argc, argv);

    #ifdef _WIN32
        cout << "Hi there, i'm a Windows Client\n" << std::endl;
    #elif __LINUX__
        cout << "Hi there, i'm a Linux Client\n" << std::endl;
    #elif TARGET_OS_X
        cout << "Hi there, i'm a Mac OS X Client\n" << std::endl;
    #endif

    ProcessTrigger processTrigger;
    processTrigger.runATray();

    SettingsReader settingsReader;
    settingsReader.initSettings();

    QList<Server> serverList = settingsReader.getServerList();

    MachineInformationController mic;
    QString Hostname = mic.getHostName();
    QString User = mic.getUserName();
    QString Domain = mic.getDomain();

    qDebug() << "Found user " << User.trimmed() << "@" << Domain << "with Hostname " << Hostname;

    while(true) {
        if (!processTrigger.isRunning()) {
            processTrigger.activateAgent(mic, serverList);
        }
    }

    a.exec();
Ich glaub ich programmier gerade ziemlichen Müll zusammen :D
MarcoG88
Beiträge: 5
Registriert: 12. April 2013 17:33

Re: Slot wird bei CLI Programm getriggert

Beitrag von MarcoG88 »

wenn es doch ein Problem mit dem QObject gäbe, bekäme ich warscheinlich beim Compilern oder
in der Ausgabe meldungen das der connect zwischen signal und slot nicht funzt. Mir
kommt es so vor, als würde der Request gar nicht erst statt finden oder das signal ins leere gehen.
MarcoG88
Beiträge: 5
Registriert: 12. April 2013 17:33

Re: Slot wird bei CLI Programm getriggert

Beitrag von MarcoG88 »

Aaaaalso. Hab jetzt einfach mal bissl mit den Pointer gespielt bzw. den Pointer vom QNetworkManager weggemacht.
Diesen habe ich dann als Referenz an den Slot übergeben:

Code: Alles auswählen

    QNetworkAccessManager manager(this);
    this->connect(&manager, SIGNAL(finished(QNetworkReply*)),
            this, SLOT(replyFinished(QNetworkReply*)));
    this->connect(&manager, SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),
                  this, SLOT(sslErrorReceived(QNetworkReply*, QList<QSslError>)));
    this->connect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)),
                  this, SLOT(authentificationRequired(QNetworkReply*, QAuthenticator*)));
    this->connect(&manager, SIGNAL(destroyed()),this, SLOT(isDestroyed()));
Was er jetzt auf einmal macht ist den "isDestroyed" Slot auszuführen, das sehe ich anhand meiner QDebug ausgabe (Siehe Bild).

Trotzdem passiert nichts bei Error oder Finished....
Dateianhänge
req.PNG
req.PNG (6.33 KiB) 5440 mal betrachtet
brax
Beiträge: 208
Registriert: 11. Mai 2010 11:22

Re: Slot wird bei CLI Programm getriggert

Beitrag von brax »

MarcoG88 hat geschrieben:Hi Christian81,

ja eine QCoreApplication existiert in der main.cpp.
Aber eigentlich wird das e.exec nie erreicht weil sich der Code
in der endlos Schleife befindet... Mache ich das a.exec weiter nach oben vor die schleife
wird das Programm nicht fortgesetzt :-/
Genau das ist wohl das Problem. Wenn der EventLoop nicht läuft (gestartet durch a.exec) werden auch keine Signal/Slot Verbindungen ausgeführt.

Was Du z.B. machen kannst, ist die Endlosschleife in einen Slot irgendwo auszulagern und den dann mit QTimer::singleShot vor dem a.exec() zu triggern.

Würde dann etwa so aussehen zum Beispiel (natürlich ungetestet):

Code: Alles auswählen

class MyLoop : public QObject {
  Q_OBJECT;
public slots:
  void start() {

    ProcessTrigger processTrigger;
    processTrigger.runATray();

    SettingsReader settingsReader;
    settingsReader.initSettings();

    QList<Server> serverList = settingsReader.getServerList();

    MachineInformationController mic;
    QString Hostname = mic.getHostName();
    QString User = mic.getUserName();
    QString Domain = mic.getDomain();

    qDebug() << "Found user " << User.trimmed() << "@" << Domain << "with Hostname " << Hostname;

    while(true) {
        if (!processTrigger.isRunning()) {
            processTrigger.activateAgent(mic, serverList);
        }
    }
}
};

int main(int argc, char** argv) {
QCoreApplication a(argc, argv);

    #ifdef _WIN32
        cout << "Hi there, i'm a Windows Client\n" << std::endl;
    #elif __LINUX__
        cout << "Hi there, i'm a Linux Client\n" << std::endl;
    #elif TARGET_OS_X
        cout << "Hi there, i'm a Mac OS X Client\n" << std::endl;
    #endif
  MyLoop loop;
  QTimer::singleShot(0, &loop, SLOT(start()));
  a.exec();
}
Wenn Du Qt5 (und einen C++11 Compiler) benutzt, kannst Du Dir die Extraklasse, denke ich, sparen und das ganze über ein Lambda machen.
MarcoG88
Beiträge: 5
Registriert: 12. April 2013 17:33

Re: Slot wird bei CLI Programm getriggert

Beitrag von MarcoG88 »

Das hat funktioniert!

Danke danke danke vielmals! Wieder was dazu gelernt :)
Qt gefällt mir immer besser
Antworten