Results 1 to 9 of 9

Thread: Why does this not work?

  1. #1
    Join Date
    Nov 2009
    Posts
    11
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Why does this not work?

    I'm trying to get the download example application to work in my application to download a file from a web site. As you can see, I've made only slight modifications to get it to work without errors, but when it returns to my main class, there is no file.

    Qt Code:
    1. #ifndef GETHTFILE_H
    2. #define GETHTFILE_H
    3.  
    4. #include <QCoreApplication>
    5. #include <QFile>
    6. #include <QFileInfo>
    7. #include <QList>
    8. #include <QNetworkAccessManager>
    9. #include <QNetworkRequest>
    10. #include <QNetworkReply>
    11. #include <QStringList>
    12. #include <QTimer>
    13. #include <QUrl>
    14.  
    15. #include <stdio.h>
    16.  
    17. class gethtfile: public QObject
    18. {
    19. Q_OBJECT
    20. QNetworkAccessManager manager;
    21. QList<QNetworkReply *> currentDownloads;
    22.  
    23. public:
    24. gethtfile();
    25. void doDownload(const QUrl &url);
    26. QString saveFileName(const QUrl &url);
    27. bool saveToDisk(const QString &filename, QIODevice *data);
    28.  
    29. public slots:
    30. void execute();
    31. void downloadFinished(QNetworkReply *reply);
    32. };
    33.  
    34. #endif // GETHTFILE_H
    To copy to clipboard, switch view to plain text mode 


    Qt Code:
    1. #include "gethtfile.h"
    2.  
    3. #include <stdio.h>
    4.  
    5. gethtfile::gethtfile()
    6. {
    7.  
    8. connect(&manager, SIGNAL(finished(QNetworkReply*)),
    9. SLOT(downloadFinished(QNetworkReply*)));
    10.  
    11. execute();
    12. }
    13.  
    14. void gethtfile::doDownload(const QUrl &url)
    15. {
    16. QString tst = url.path();
    17. QNetworkRequest request(url);
    18. QNetworkReply *reply = manager.get(request);
    19. currentDownloads.append(reply);
    20. }
    21.  
    22. QString gethtfile::saveFileName(const QUrl &url)
    23. {
    24. QString path = url.path();
    25. QString basename = QFileInfo(path).fileName();
    26.  
    27. if (basename.isEmpty())
    28. basename = "download";
    29.  
    30. if (QFile::exists(basename)) {
    31. // already exists, don't overwrite
    32. int i = 0;
    33. basename += '.';
    34. while (QFile::exists(basename + QString::number(i)))
    35. ++i;
    36.  
    37. basename += QString::number(i);
    38. }
    39.  
    40. return basename;
    41. }
    42.  
    43. bool gethtfile::saveToDisk(const QString &filename, QIODevice *data)
    44. {
    45. QFile file(filename);
    46. if (!file.open(QIODevice::WriteOnly)) {
    47. fprintf(stderr, "Could not open %s for writing: %s\n",
    48. qPrintable(filename),
    49. qPrintable(file.errorString()));
    50. return false;
    51. }
    52.  
    53. file.write(data->readAll());
    54. file.close();
    55.  
    56. return true;
    57. }
    58.  
    59. void gethtfile::execute()
    60. {
    61. QUrl url;
    62. url.setUrl("http://www.google.com/robots.txt");
    63. doDownload(url);
    64.  
    65. }
    66.  
    67. void gethtfile::downloadFinished(QNetworkReply *reply)
    68. {
    69. QUrl url = reply->url();
    70. if (reply->error()) {
    71. fprintf(stderr, "Download of %s failed: %s\n",
    72. url.toEncoded().constData(),
    73. qPrintable(reply->errorString()));
    74. } else {
    75. QString filename = saveFileName(url);
    76. if (saveToDisk(filename, reply))
    77. printf("Download of %s succeded (saved to %s)\n",
    78. url.toEncoded().constData(), qPrintable(filename));
    79. }
    80.  
    81. currentDownloads.removeAll(reply);
    82. reply->deleteLater();
    83.  
    84. if (currentDownloads.isEmpty())
    85. // all downloads finished
    86. QCoreApplication::instance()->quit();
    87. }
    To copy to clipboard, switch view to plain text mode 

    I've been tearing my hair out for three days trying to use QT to get the file. Why is it so hard to use QHTTP and/or QNetworkAccessManager? All I need is a simple way to get a small text file from a web site. I can easily do it with libcurl, but I don't want to add an external library when QT can (or should) be able to do it.

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Why does this not work?

    You are forgetting these classes work in an asynchronous manner. When your code returns the data will not have been downloaded yet. If you want blocking semantics, you need to provide it yourself, i.e. using QEventLoop.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Nov 2009
    Posts
    11
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Why does this not work?

    Thank you wysota, I added the QEventLoop to the doDownload function like so:

    Qt Code:
    1. void gethtfile::doDownload(const QUrl &url)
    2. {
    3. QEventLoop loop;
    4. QString tst = url.path();
    5. QNetworkRequest request(url);
    6. QNetworkReply *reply = manager.get(request);
    7. connect(reply, SIGNAL(downloadFinished(QNetworkReply*)), &loop, SLOT(quit()));
    8. // currentDownloads.append(reply);
    9. loop.exec();
    10. }
    To copy to clipboard, switch view to plain text mode 

    I commented out the append line as we'll only be getting one file at a time anyway. It works, but I get the following when I run:

    Object::connect: No such slot QEventLoop::downloadFinished(QNetworkReply*) in src/gethtfile.cpp:24

    I tried both downloadFinished(QNetworkReply*) and finished(QNetworkReply*) and both give the error (warning?) in the console.

    What causes that, and how can I prevent it?

    QT really does need a simple QHttpGetSingleFileWithNoThreading type function so we don't need to write 100+ lines of code for a simple one time small download.

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Why does this not work?

    Quote Originally Posted by lnxusr View Post
    It works, but I get the following when I run:

    Object::connect: No such slot QEventLoop::downloadFinished(QNetworkReply*) in src/gethtfile.cpp:24

    I tried both downloadFinished(QNetworkReply*) and finished(QNetworkReply*) and both give the error (warning?) in the console.

    What causes that, and how can I prevent it?
    There is no such slot in QEventLoop, right? So the message is obvious.

    QT really does need a simple QHttpGetSingleFileWithNoThreading type function so we don't need to write 100+ lines of code for a simple one time small download.
    There is no threading involved here. Qt just works in an asynchronous way and you need to accept it. It's like you complained because a dog barked while you were used to the fact that animals made different voices just because you always had cats.

    Qt Code:
    1. QNetworkReply *reply = manager->get(QNetworkRequest(...));
    2. connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
    3. QTimer timer;
    4. connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); // just in case
    5. timer.start(5000);
    6. loop.exec();
    7. QByteArray result = reply->readAll();
    To copy to clipboard, switch view to plain text mode 
    No 100 lines of code...
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. The following user says thank you to wysota for this useful post:

    lnxusr (17th December 2009)

  6. #5
    Join Date
    Nov 2009
    Posts
    11
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Why does this not work?

    Quote Originally Posted by wysota View Post
    There is no such slot in QEventLoop, right? So the message is obvious.
    Well yeah, to those who know what they're doing.. ;/

    I don't get the error the first time I used up top. Would thedownloadFinished(QNetworkReply*) slot not still be valid, or can you only use them once?

    Quote Originally Posted by wysota View Post
    There is no threading involved here. Qt just works in an asynchronous way and you need to accept it. It's like you complained because a dog barked while you were used to the fact that animals made different voices just because you always had cats.
    Don't let my cats here you talking about dogs...

    I'm writing this app to learn not only QT, but C++ as well. It'll take me a while to get the hang of the OO world. I've ordered a couple of books to help out. QT's documentation is not easy to follow if you don't know the basics of C++, but I'm still working on the app anyway. It's a mess, but things are working. I'll clean up the code as I learn different things.

    Thanks for that snippet, it cleaned the class down to around 40 lines (including all the #includes). I just added six lines to save the data to a file. Most of the stuff in the download example wasn't needed, and I would have cleaned it out further, but nowhere near to the eight lines you gave.

  7. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Why does this not work?

    Quote Originally Posted by lnxusr View Post
    Well yeah, to those who know what they're doing.. ;/
    Or maybe to those that can read English

    I don't get the error the first time I used up top. Would thedownloadFinished(QNetworkReply*) slot not still be valid, or can you only use them once?
    I completly don't understand wha tou mean.


    I'm writing this app to learn not only QT, but C++ as well.
    If you want to learn QT you have to go to Appple forums. Here you can only learn Qt.

    It'll take me a while to get the hang of the OO world.
    OO has nothing to do with asynchronous execution.

    QT's documentation is not easy to follow if you don't know the basics of C++, but I'm still working on the app anyway.
    You should really learn C++ first before taking on Qt. You'll save yourself lots of time.

    By the way, if all you wanted was to save the download to a file, you might have done it in much shorter code.

    Qt Code:
    1. QHttp *http = new QHttp(this);
    2. http->setHost(...);
    3. QFile *file = new QFile("...");
    4. file->open(QFile::WriteOnly);
    5. http->get("...", file);
    To copy to clipboard, switch view to plain text mode 
    And that's it.

    Alternatively with QNetworkAccessManager:
    Qt Code:
    1. QNetworkReply *reply = manager->get(...);
    2. connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(saveToFile(QNetworkReply*)));
    3. //...
    4. void ThisClass::saveToFile(QNetworkReply *reply) {
    5. QFile f(...);
    6. f.open(...);
    7. f.write(reply->readAll());
    8. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by wysota; 17th December 2009 at 08:44.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  8. The following user says thank you to wysota for this useful post:

    lnxusr (17th December 2009)

  9. #7
    Join Date
    Nov 2009
    Posts
    11
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Why does this not work?

    Quote Originally Posted by wysota View Post
    I completly don't understand wha tou mean.
    In my original post. The first statement of the gethtfile class is

    Qt Code:
    1. connect(&manager, SIGNAL(finished(QNetworkReply*)),
    2. SLOT(downloadFinished(QNetworkReply*)));
    To copy to clipboard, switch view to plain text mode 

    I don't get an the warning message from this, but did when I connect again in the event loop in doDownload.

    You should really learn C++ first before taking on Qt. You'll save yourself lots of time.
    I know, but until I get the books I ordered, I'll still play around with my app. I have nothing else to work on right now, and it fills my free time. It may be frustrating, but I am slowly figuring things out. Like I said before, things work, but it's nowhere near usable. It's more of a hodge podge of classes and functions for testing and seeing how things work. I don't know if you can really call it an app or not. I'll most likely start from scratch or rewrite 95% of what I've done, but I am learning a few things.

    While searching the forums, I see alot of people saying QHttp is depreciated and to use QNetworkManager. That's why I moved away from it. It sounds like, in the future (5.0?) Qt will do away with QHttp.

    By the way, if all you wanted was to save the download to a file, you might have done it in much shorter code.
    Thanks for the snippets, I'll add them to my notes..

  10. #8
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Why does this not work?

    Quote Originally Posted by lnxusr View Post
    I have nothing else to work on right now, and it fills my free time.
    I suggest reading these:
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  11. #9
    Join Date
    Nov 2009
    Posts
    11
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Why does this not work?

    Great! Thanks wysota,

    I read the preface and scanned through the first volume last night. Looks pretty well organized, and I think it may be just what I need. Awesome reviews on Amazon as well. I may see about getting hard copies from Abebooks.

    The second volume has some macro's in it. I have OpenOffice set to disable macros, are they required to use the book? Also not sure if word macros will work properly in OOo.

Similar Threads

  1. Making MySQL plugin work on a windows x86 enviroment
    By Baasie in forum Installation and Deployment
    Replies: 1
    Last Post: 2nd September 2009, 15:15
  2. getting MySQL to work with Qt
    By Ashish in forum Installation and Deployment
    Replies: 7
    Last Post: 19th May 2009, 08:57
  3. Qt4 : QPainter::setRedirected doesn't work
    By Ankitha Varsha in forum Qt Programming
    Replies: 2
    Last Post: 20th June 2008, 17:52
  4. QActions don't work with menubar hidden
    By Pepe in forum Qt Programming
    Replies: 1
    Last Post: 16th August 2007, 01:04
  5. Change work area OS
    By pakulo in forum Qt Programming
    Replies: 15
    Last Post: 15th May 2007, 07:20

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.