Use qobject using signal and slots.



  • I want to connect to my class since outside so i want to use qobject but i really have problems with this.
    Code:
    main.cpp:

    #include <QCoreApplication>
    #include "downloader.h"
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        Downloader d;
        d.doDownload("http://myweb/currxml.php");
    
        return a.exec();
    }
    
    

    downloader.cpp:

    #include "downloader.h"
    
    Downloader::Downloader(QObject *parent) :
        QObject(parent)
    {
    }
    
    void Downloader::doDownload(QString s)
    {
        manager = new QNetworkAccessManager(this);
        connect(manager, SIGNAL(finished(QNetworkReply*)),
                this, SLOT(replyFinished(QNetworkReply*)));
    
        manager->get(QNetworkRequest(QUrl(s)));
    }
    
    void Downloader::replyFinished (QNetworkReply *reply)
    {
        if(reply->error())
        {
            qDebug() << "ERROR!";
            qDebug() << reply->errorString();
        }
        else
        {
            //qDebug() << reply->header(QNetworkRequest::ContentTypeHeader).toString();
            //qDebug() << reply->header(QNetworkRequest::LastModifiedHeader).toDateTime().toString();
            //qDebug() << reply->header(QNetworkRequest::ContentLengthHeader).toULongLong();
            //qDebug() << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
            //qDebug() << reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString();
            QString p = reply->request().url().fileName();
            QFile *file = new QFile("C:/Users/moh/"+p);
            if(file->open(QFile::Append))
            {
                file->write(reply->readAll());
                file->flush();
                file->close();
            }
            delete file;
        }
    
        reply->deleteLater();
    }
    
    

    downloader.h:

    #ifndef DOWNLOADER_H
    #define DOWNLOADER_H
    
    #include <QObject>
    #include <QNetworkAccessManager>
    #include <QNetworkRequest>
    #include <QNetworkReply>
    #include <QUrl>
    #include <QDateTime>
    #include <QFile>
    #include <QDebug>
    
    class Downloader : public QObject
    {
        Q_OBJECT
    public:
        explicit Downloader(QObject *parent = 0);
    
        void doDownload(QString s);
        QString r;
    
    signals:
    
    public slots:
        void replyFinished (QNetworkReply *reply);
    
    private:
       QNetworkAccessManager *manager;
    
    };
    
    #endif // DOWNLOADER_H
    
    

    In the old questions i used singleton but i was wrong i dont need to use singletone instance i want to call my signal and slot with qobject::connect... only.


  • Moderators

    @Jeronimo

    The only thing I see is that you are starting the download and your event loop is not ruunning yet.
    The event loop is started in line:

     return a.exec();
    

    when you do

    d.doDownload("http://myweb/currxml.php");
    

    this is before you start the event loop.
    doDownload does apparently everything as it should be, but very likely the return of your get

    manager->get(QNetworkRequest(QUrl(s)));
    

    before the application has a chance to start the event loop. Therefore your request will go to empty space and is forgotten.

    You can delay the request with QTimer for instance.

    #ifndef DOWNLOADER_H
    #define DOWNLOADER_H
    
    #include <QObject>
    #include <QNetworkAccessManager>
    #include <QNetworkRequest>
    #include <QNetworkReply>
    #include <QUrl>
    #include <QDateTime>
    #include <QFile>
    #include <QDebug>
    
    class Downloader : public QObject
    {
        Q_OBJECT
    public:
        explicit Downloader(QObject *parent = 0);
    
        void doDownload(QString s);
        QString r;
    
    signals:
    
    public slots:
        void replyFinished (QNetworkReply *reply);
        void startDowload ();
    
    private:
       QNetworkAccessManager *manager;
    
    };
    #endif // DOWNLOADER_H
    
    #include "downloader.h"
    
    Downloader::Downloader(QObject *parent) :
        QObject(parent)
    {
    }
    
    void Downloader::doDownload(QString s)
    {
        manager = new QNetworkAccessManager(this);
        connect(manager, SIGNAL(finished(QNetworkReply*)),
                this, SLOT(replyFinished(QNetworkReply*)));
    
        // manager->get(QNetworkRequest(QUrl(s)));
    }
    
    void Downloader::startDownload()
    {
          manager->get(QNetworkRequest(QUrl(s)));
    }
    
    ...
    
    #include <QCoreApplication>
    #include <QTimer>
    #include "downloader.h"
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        Downloader d;
        d.doDownload("http://myweb/currxml.php");
    
    // starts startDownload with a delay of 
    // 1000milliseconds
        QTimer::singleShot ( 1000, &d, SLOT(startDownload() );
        return a.exec();
    }
    

    Check it out if this works. Just brain to keyboard


  • Moderators

    @Jeronimo

    Sorry, previous post cannot work. I have lost the overview the code lines.

    You can delay the request with QTimer for instance.

    #ifndef DOWNLOADER_H
    #define DOWNLOADER_H
    
    #include <QObject>
    #include <QNetworkAccessManager>
    #include <QNetworkRequest>
    #include <QNetworkReply>
    #include <QUrl>
    #include <QDateTime>
    #include <QFile>
    #include <QDebug>
    
    class Downloader : public QObject
    {
        Q_OBJECT
    public:
        explicit Downloader(QObject *parent = 0);
    
        void doDownload(QString s);
        QString r;
    
    signals:
    
    public slots:
        void replyFinished (QNetworkReply *reply);
        void startDowload ();
    
    private:
       QNetworkAccessManager *manager;
       QString   webAddress;
    };
    #endif // DOWNLOADER_H
    
    #include "downloader.h"
    
    Downloader::Downloader(QObject *parent) :
        QObject(parent)
    {
    }
    
    void Downloader::doDownload(QString s)
    {
        manager = new QNetworkAccessManager(this);
        connect(manager, SIGNAL(finished(QNetworkReply*)),
                this, SLOT(replyFinished(QNetworkReply*)));
         webAddress = s;
        // manager->get(QNetworkRequest(QUrl(s)));
    }
    
    void Downloader::startDownload()
    {
          manager->get(QNetworkRequest(QUrl(webAddress)));
    }
    
    ...
    
    #include <QCoreApplication>
    #include <QTimer>
    #include "downloader.h"
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        Downloader d;
        d.doDownload("http://myweb/currxml.php");
    
    // starts startDownload with a delay of 
    // 1000milliseconds
        QTimer::singleShot ( 1000, &d, SLOT(startDownload() );
        return a.exec();
    }
    

    This looks better, check it out if this works. Again just brain to keyboard



  • @koahnig ok i will check your code but the code works but it's impossible to call with qobject::connect since my main program?? thx in advance.
    Like
    Main.cpp:

    ..code..
    and then..
    ->QObject::connect(..SIGNAL...SLOT..);

    Anyways i will check new code you take me maybe it's useful for me thxx a lot.


  • Moderators

    @Jeronimo

    What do you like to connect in your main program?
    Connect is typically used to connect two objects, but you have only one.

    You could connect a signal from an object to a slot in the same object, but why do you want to do this outside, when you can do it with the object's code.

    While looking for example for you, I have found the example you are probably using.
    Is this the place where you gout your example code from?



  • @koahnig hi koahning yeah is the example but in this example that you took or other i want to use since main function QObject::connect because i want to use since outside my class. So for example in the main i will include something like:
    QObject::connect(..instance or call my slot.....). If i need to include two object so ok it's good.

    i need something like this to call my class since outside because is the only way in my case works.
    In this post you can get more details about the code:
    https://forum.qt.io/topic/72574/question-about-qobject-and-http

    Is similar code but my question is different i dont want to use singleton pattern only to connect with qobject.


  • Moderators

    @Jeronimo

    As it looks you like to include most or even all your statements and logic into your main program. I am strongly recommending NOT to do this.

    Just imagine, you have a couple of pages of code which you are executing until the end. The end is "return a.exec();". That is the point where all processing of events are starting. Any connect before reaching the last will not result in execution of an event because the event loop is not started.

    You cannot move the statement further up, because the program will stay in the event loop until you explicitely quitting or exiting the event loop.



  • This post is deleted!


  • This post is deleted!

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.