Slot never called



  • Hello everyone.
    I'm trying to make this code works
    http://www.bogotobogo.com/Qt/Qt5_Downloading_Files_QNetworkAccessManager_QNetworkRequest.php

    I'm put a qDebug() << "running"; inside the slot to test.
    But the slot "**replyFinished **" is never called.

    The only difference is the main function that i'm not using.

    The below code is inside another method, and works.

    Downloader d;
    d.doDownload();
    

    What is wrong?!

    Thanks in advance!


  • Moderators

    The only difference is the main function that i'm not using.

    And that's the problem.
    Since you put the downloader in some method it goes out of scope and is destroyed, ie.

    void someFunction() {
       Downloader d;       //d is created here
       d.doDownload();
    }                      //d is destroyed here
    

    The difference is that in the example downloader is created in the main() and right after doDownload() is called the appplication enters an event loop: return a.exec();, which blocks until the download is finished, so the downloader does not exit the scope.

    To fix this either put Downloader instance in a scope that is wide enough or create it on the heap and delete after the download is finished.



  • @Chris-Kawa

    Great explanation!

    But if I want use within this function?
    Create it on the heap is the solution?
    How can I do this?

    Thanks.


  • Moderators

    How can you create an instance on the heap? Just as with any other c++ class: with the new keyword.

        Downloader* d = new Downloader();
        d->doDownload();
    

    but that is leaking memory, so you need to make sure the downloader is deleted when it finishes. You could, for example, emit a signal when it's done:

    class Downloader : public QObject
    {
       ...
    signals:
       void finished() const;
       ...
    

    Emit it in the replyFinished():

    void Downloader::replyFinished (QNetworkReply *reply)
    {
       ...
        reply->deleteLater();
        emit finished(); 
    }
    

    and then you can use it like this:

    void someFunction()
    {
        Downloader* d = new Downloader();
        d->doDownload();
        connect(d, &Downloader::finished, d, &Downloader::deleteLater);
    }
    


  • @Chris-Kawa
    Yes! Now it is being called!

    Now i'm getting a compile error:

    C2248: 'Downloader::finished' : cannot access protected member declared in class 'Downloader'

    signals:
    void finished() const;



  • Hi,
    please post the full source code.


  • Moderators

    @Helson said:

    C2248: 'Downloader::finished' : cannot access protected member declared in class 'Downloader'

    Looks like you misplaced something. finished() should be a public method (a signal). Posting your code is a good idea as @Wieland suggested.



  • Here is the code:

    http://pastebin.com/H9dVD3QZ


  • Qt Champions 2016

    Hi
    note:
    its Qt4


  • Qt Champions 2016

    @Chris-Kawa

    Looks like you misplaced something. finished() should be a public method (a signal).

    Chris, in Qt4 signals used to be protected, so it might be simply that he's using a bit older version than we assumed. ;)


  • Moderators

    awww, ok. Good catch guys.

    @Helson so just replace

    connect(d, &Downloader::finished, d, &Downloader::deleteLater);
    

    with

    connect(d, SIGNAL(finished()), d, SLOT(deleteLater()));
    

    and think about upgrading to Qt5. Especially since you're following tutorials there's no point in learning obsolete stuff.


  • Qt Champions 2016

    @Chris-Kawa said:
    connect(d, SIGNAL(finished()), d, SLOT(deleteLater()));

    we did. still said it was protected ?!
    so we moved to ctor in Download class


  • Moderators

    @mrjj

    so we moved to ctor in Download class

    Don't do that. It makes your class dependent on being created on the heap, which you can't guarantee. If someone creates it on the stack you will crash on double delete.


  • Qt Champions 2016

    @Chris-Kawa
    Ah yes I see. Luckily we did not do it, ;)
    we moved to dodownload member function and
    used old syntax.

    Im not used to Qt4 so the whole protected signals were
    confusing.


  • Qt Champions 2016

    Im not used to Qt4 so the whole protected signals were
    confusing.

    If you think about it, semantically it's more correct that signals are protected. A signal is raised from the object itself to notify others and in principle shouldn't be available for others to emit it! My suspicion is that they're now public because of the new way of connecting, which by my opinion is not such an improvement over the old one.

    PS.
    Is it me, or the forum is going nuts? I have the distinct feeling that I see Helson's posts as mrjj's?


  • Qt Champions 2016

    hi, I talked with him in chat also, so I did post here.
    Forums crash every 2 minutes for me though.


  • Qt Champions 2016

    @mrjj
    Yes, but who are you? Are you indeed mrjj, or there's some bug in the forum and you're in fact Helson? :)


  • Qt Champions 2016

    @kshegunov
    Heh. Im mrjj
    (i hope)


  • Qt Champions 2016

    @mrjj
    Ok, because I would have expected this:

    Ah yes I see. Luckily we did not do it, ;)
    we moved to dodownload member function and
    used old syntax.

    to be written by Helson. So it's my mistake, sorry for the misunderstanding. :)


  • Qt Champions 2016

    @kshegunov
    well You should have the credits as you solved it :)
    and sorry for writing a bit unclear :)


  • Qt Champions 2016

    @mrjj
    Thanks for the credits, although I'm not sure how much I care about them, still I appreciate the sentiment. :)


Log in to reply
 

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