Results 1 to 17 of 17

Thread: [QT 5.0] Downloading from a URL then saving to client-defined path/filename?

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Jan 2013
    Location
    Temecula, CA
    Posts
    19
    Thanks
    11
    Qt products
    Qt5
    Platforms
    Windows

    Default [QT 5.0] Downloading from a URL then saving to client-defined path/filename?

    I'm trying to make a program that downloads an image and saves it to the disk. Using C++ I've followed a reference for the downloading of a file, but how would I save it to disk? My code as I have it now gives me allot of unresolved external symbols. When I comment out lines 40 - 44 everything compiles successfully..

    My Code: (I ended up putting everything under the button clicked function)
    Qt Code:
    1. #include "minecraftskindownloader.h"
    2. #include "ui_minecraftskindownloader.h"
    3. #include <QWidget>
    4. #include <QObject>
    5. #include <QtNetwork/QNetworkAccessManager>
    6. #include <QFileDialog>
    7. #include <C:\Qt\Qt5.0.0\5.0.0\msvc2010\include\QtNetwork\QNetworkRequest>
    8. #include <QDebug>
    9. #include <QUrl>
    10. #include <QFile>
    11.  
    12. MinecraftSkinDownloader::MinecraftSkinDownloader(QWidget *parent) :
    13. QMainWindow(parent),
    14. ui(new Ui::MinecraftSkinDownloader)
    15. {
    16. ui->setupUi(this);
    17. this->setWindowTitle("Minecraft Skin Downloader");
    18. setFixedSize(400, 200);
    19. }
    20.  
    21. MinecraftSkinDownloader::~MinecraftSkinDownloader()
    22. {
    23. delete ui;
    24. }
    25.  
    26. void MinecraftSkinDownloader::on_actionClose_triggered()
    27. {
    28. qApp->quit();
    29. }
    30. //http://s3.amazonaws.com/MinecraftSkins/USERNAMEHERE.png
    31.  
    32. void MinecraftSkinDownloader::on_pushButton_clicked()
    33. {
    34. QString prefix = "http://s3.amazonaws.com/MinecraftSkins/";
    35. QString url = prefix += ui->lineEdit->text();
    36. url += ".png";
    37.  
    38. ui->textEdit->setText(url); //Just testing the link part
    39.  
    40. QNetworkAccessManager *manager = new QNetworkAccessManager(this);
    41. connect(manager, SIGNAL(finished(QNetworkReply*)),
    42. SLOT(replyFinished(QNetworkReply*)));
    43.  
    44. manager->get(QNetworkRequest(QUrl(url)));
    45.  
    46. QString fileName = QFileDialog::getSaveFileName(this, tr("Save"),"/Documents",tr("Images (*.png)"));
    47.  
    48. }
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: [QT 5.0] Downloading from a URL then saving to client-defined path/filename?

    You are probably missing:
    Qt Code:
    1. QT += network
    To copy to clipboard, switch view to plain text mode 
    in your pro file.

    Get your desired file name and open a file for writing. Store the QFile instance as a member variable.
    Connect the QNetworkReply object readyRead() signal to a slot that can handle it.
    In your readyRead() handler write all received bytes to the file.
    In your finished() handler: If there has been no error then simply close the file, otherwise delete the partial file and report the error.

  3. The following user says thank you to ChrisW67 for this useful post:

    Salads (20th January 2013)

  4. #3
    Join Date
    Jan 2013
    Location
    Temecula, CA
    Posts
    19
    Thanks
    11
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: [QT 5.0] Downloading from a URL then saving to client-defined path/filename?

    Thanks for the reply, but I'm having a bit of trouble understanding the pseudo-code.. Where do I start with the readyRead() signal? I also decided to add a separate button for a "Save As" function.
    Which is the QNetworkReply Object? I was thinking about storing everything in a QByteArray and then streaming that to the filebut I don't have an idea how to do that since I don't know what variable the downloaded data is stored..
    I might as well and come out that I'm almost a complete beginner, starting QT only a couple days ago..

    Here's my code so far:
    Qt Code:
    1. #ifndef MINECRAFTSKINDOWNLOADER_H
    2. #define MINECRAFTSKINDOWNLOADER_H
    3.  
    4. #include <QMainWindow>
    5.  
    6. namespace Ui {
    7. class MinecraftSkinDownloader;
    8. }
    9.  
    10. class MinecraftSkinDownloader : public QMainWindow
    11. {
    12. Q_OBJECT
    13.  
    14. public:
    15. explicit MinecraftSkinDownloader(QWidget *parent = 0);
    16. ~MinecraftSkinDownloader();
    17.  
    18. private slots:
    19. void on_actionClose_triggered();
    20.  
    21. void on_pushButton_clicked();
    22.  
    23. void on_saveAs_clicked();
    24.  
    25. private:
    26. Ui::MinecraftSkinDownloader *ui;
    27.  
    28. };
    29.  
    30. #endif // MINECRAFTSKINDOWNLOADER_H
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. #include "minecraftskindownloader.h"
    2. #include <QApplication>
    3.  
    4. int main(int argc, char *argv[])
    5. {
    6. QApplication a(argc, argv);
    7. MinecraftSkinDownloader w;
    8. w.show();
    9.  
    10. return a.exec();
    11. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. #include "minecraftskindownloader.h"
    2. #include "ui_minecraftskindownloader.h"
    3. #include <QWidget>
    4. #include <QObject>
    5. #include <QtNetwork/QNetworkAccessManager>
    6. #include <QFileDialog>
    7. #include <QtNetwork/QNetworkRequest>
    8. #include <QDebug>
    9. #include <QUrl>
    10. #include <QFile>
    11.  
    12. MinecraftSkinDownloader::MinecraftSkinDownloader(QWidget *parent) :
    13. QMainWindow(parent),
    14. ui(new Ui::MinecraftSkinDownloader)
    15. {
    16. ui->setupUi(this);
    17. this->setWindowTitle("Minecraft Skin Downloader");
    18. setFixedSize(400, 200);
    19. }
    20.  
    21. MinecraftSkinDownloader::~MinecraftSkinDownloader()
    22. {
    23. delete ui;
    24. }
    25.  
    26. void MinecraftSkinDownloader::on_actionClose_triggered()
    27. {
    28. qApp->quit();
    29. }
    30. //http://s3.amazonaws.com/MinecraftSkins/USERNAMEHERE.png
    31.  
    32. void MinecraftSkinDownloader::on_pushButton_clicked()
    33. {
    34. QString prefix = "http://s3.amazonaws.com/MinecraftSkins/";
    35. QString url = prefix += ui->lineEdit->text();
    36. url += ".png";
    37.  
    38. ui->textEdit->setText(url); //Just testing the link part
    39.  
    40. QNetworkAccessManager *manager = new QNetworkAccessManager(this);
    41. connect(manager, SIGNAL(finished(QNetworkReply*)),
    42. SLOT(replyFinished(QNetworkReply*)));
    43.  
    44. manager->get(QNetworkRequest(QUrl(url)));
    45. }
    46.  
    47. void MinecraftSkinDownloader::on_saveAs_clicked()
    48. {
    49.  
    50. QString filename = QFileDialog::getSaveFileName(this, tr("Save As..."),
    51. "C:/Users/",
    52. tr("*.png"));
    53.  
    54. }
    To copy to clipboard, switch view to plain text mode 

  5. #4
    Join Date
    Jan 2013
    Location
    Temecula, CA
    Posts
    19
    Thanks
    11
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: [QT 5.0] Downloading from a URL then saving to client-defined path/filename?

    Sorry, yeah I just ran qmake and everything started magically working. Thanks for the += network tip, wouldn't have gotten it otherwise.

  6. #5
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: [QT 5.0] Downloading from a URL then saving to client-defined path/filename?

    There are several ways to achieve what you want. Each has its advantages/disadvantages. In all cases the QNetworkAccessManager get() or post() returns a QNetworkReply object (pointer) that you can use to access downloaded data, errors etc. This object will emit readyRead() signals when data arrives and could be written to file, a finished() signal when the transaction finishes (error or not), and two error signals. See the QNetworkAccessManager docs for how these are typically connected.

    You can look at the Network Download Manager Example
    and Network Download Example for a complete downloader (no UI).
    Last edited by ChrisW67; 20th January 2013 at 21:55.

  7. The following user says thank you to ChrisW67 for this useful post:

    Salads (21st January 2013)

  8. #6
    Join Date
    Jan 2013
    Location
    Temecula, CA
    Posts
    19
    Thanks
    11
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: [QT 5.0] Downloading from a URL then saving to client-defined path/filename?

    Thanks, that helped me allot. But a weird problem came since then. I tried to make a Save As button, but now when I run it it doesn't do anything. I tried looking in the header file for anything that would be amiss, and even tried to use a connect statement. But I keep getting the error code "QMetaObject::connectSlotsByName: No matching signal for on_saveAs_clicked(QNetworkReply*)"

    What's weird is that "No matching signal for on_saveAs_clicked(QNetworkReply*)" does not have to same arguments as the function in my .cpp/.h file. There, it's on_saveAs_clicked(QNetworkReply *reply).

    Have a look: (.cpp)
    Qt Code:
    1. void MinecraftSkinDownloader::on_pushButton_clicked()
    2. {
    3. QString prefix = "http://s3.amazonaws.com/MinecraftSkins/";
    4. QString usrl = prefix += ui->lineEdit->text() += ".png";
    5.  
    6. QNetworkAccessManager *manager = new QNetworkAccessManager(this);
    7. connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(slot_netwManagerFinished(QNetworkReply*)));
    8. connect(ui->saveAs, SIGNAL(clicked()), this, SLOT(on_saveAs_clicked(QNetworkReply*)));
    9.  
    10.  
    11. QUrl url(usrl);
    12. QNetworkRequest request(url);
    13.  
    14. manager->get(request);
    15.  
    16. }
    17.  
    18. void MinecraftSkinDownloader::slot_netwManagerFinished(QNetworkReply *reply)
    19. {
    20.  
    21. if (reply->error() != QNetworkReply::NoError)
    22. {
    23. qDebug() << "Error in" << reply->url() << ":" << reply->errorString();
    24. NoUser mDiag;
    25. mDiag.setModal(true);
    26. mDiag.exec();
    27. return;
    28. }
    29.  
    30. QByteArray jpegData = reply->readAll();
    31. QPixmap pixmap;
    32. pixmap.loadFromData(jpegData);
    33. QPixmap scaled = pixmap.scaled(128,64,Qt::IgnoreAspectRatio, Qt::FastTransformation);
    34. ui->preview->setPixmap(scaled);
    35. }
    36.  
    37. void MinecraftSkinDownloader::on_saveAs_clicked(QNetworkReply *reply)
    38. {
    39. QString filename = QFileDialog::getSaveFileName(this, tr("Save Skin"), "C:/Users", tr("PNG Image (*.png)"));
    40. QFile file (filename);
    41. file.open(QIODevice::WriteOnly);
    42. QDataStream out (&file);
    43. out << reply;
    44. file.close();
    45. }
    To copy to clipboard, switch view to plain text mode 
    .h
    Qt Code:
    1. #ifndef MINECRAFTSKINDOWNLOADER_H
    2. #define MINECRAFTSKINDOWNLOADER_H
    3.  
    4. #include <QMainWindow>
    5. #include <QtNetwork/QNetworkReply>
    6.  
    7. namespace Ui {
    8. class MinecraftSkinDownloader;
    9. }
    10.  
    11. class MinecraftSkinDownloader : public QMainWindow
    12. {
    13. Q_OBJECT
    14.  
    15. public:
    16. explicit MinecraftSkinDownloader(QWidget *parent = 0);
    17. ~MinecraftSkinDownloader();
    18.  
    19. private slots:
    20.  
    21. void on_pushButton_clicked();
    22.  
    23. void slot_netwManagerFinished(QNetworkReply *reply);
    24.  
    25. void on_saveAs_clicked(QNetworkReply *reply);
    26.  
    27. private:
    28. Ui::MinecraftSkinDownloader *ui;
    29.  
    30. };
    31.  
    32. #endif // MINECRAFTSKINDOWNLOADER_H
    To copy to clipboard, switch view to plain text mode 

    Screenshot of error:http://i.imgur.com/zNHfnzG.png

  9. #7
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: [QT 5.0] Downloading from a URL then saving to client-defined path/filename?

    The name you have chosen is being picked up by QMetaObject::connectSlotsByName() in your UI generated code. It goes looking for an object in the UI called "saveAs" with a slot called "clicked" and finds that, while the saveAs button has one, its arguments do not match your slot. You need to rename the slot or rethink why you want the QNetworkReply* in that slot.

    As an aside, you certainly do not want QDataStream involved in writing a PNG file retrieved from a QIODevice. Use QIOdevice::write() directly.

  10. The following user says thank you to ChrisW67 for this useful post:

    Salads (21st January 2013)

  11. #8
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: [QT 5.0] Downloading from a URL then saving to client-defined path/filename?

    And you cannot connect a signal with no arguments (clicked()) to a slot with arguments.

    Cheers,
    _

  12. The following user says thank you to anda_skoa for this useful post:

    Salads (21st January 2013)

  13. #9
    Join Date
    Jan 2013
    Location
    Temecula, CA
    Posts
    19
    Thanks
    11
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: [QT 5.0] Downloading from a URL then saving to client-defined path/filename?

    Thanks for the help, I was able to fix the Save As dialog from not appearing.. But now how would I pass data from my slot_netwManagerFinished(QNetworkReply *reply) function to the on_saveAs_clicked() function?
    I want to either pass pixmap or jpegData to the SaveAs function so I can actually save it. (Adding variables to the function made it break) Would adding the button in manually do the job as well because of the variables? I still would prefer if I could just add the argument in..

    Code:
    Qt Code:
    1. void MinecraftSkinDownloader::slot_netwManagerFinished(QNetworkReply *reply)
    2. {
    3.  
    4. if (reply->error() != QNetworkReply::NoError)
    5. {
    6. qDebug() << "Error in" << reply->url() << ":" << reply->errorString();
    7. NoUser mDiag;
    8. mDiag.setModal(true);
    9. mDiag.exec();
    10. return;
    11. }
    12.  
    13. QByteArray jpegData = reply->readAll(); //or this
    14. QPixmap pixmap; //<-- This one here
    15. pixmap.loadFromData(jpegData);
    16. QPixmap scaled = pixmap.scaled(128,64,Qt::IgnoreAspectRatio, Qt::FastTransformation);
    17. ui->preview->setPixmap(scaled);
    18.  
    19. }
    20.  
    21. void MinecraftSkinDownloader::on_saveAs_clicked()
    22. {
    23. QString filename = QFileDialog::getSaveFileName(this, tr("Save Skin"), "C:/Users/", ("PNG Image (*.png)"));
    24.  
    25. QFile file(filename);
    26. file.open(QIODevice::WriteOnly);
    27. file.write(pixmap); //<-- Want to use here
    28. file.close();
    29.  
    30. }
    To copy to clipboard, switch view to plain text mode 

  14. #10
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: [QT 5.0] Downloading from a URL then saving to client-defined path/filename?

    If you want jpegData to be available to other member functions of the class then make it a member variable in the class rather than a local variable of the function.

  15. The following user says thank you to ChrisW67 for this useful post:

    Salads (22nd January 2013)

  16. #11
    Join Date
    Jan 2013
    Location
    Temecula, CA
    Posts
    19
    Thanks
    11
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: [QT 5.0] Downloading from a URL then saving to client-defined path/filename?

    Thanks! Sorry I should have known that one from the beginning. (Maybe I'll go finish off C++ Primer before I do more QT eh? ) After I fixed my code for using a class variable the connectSlotsByName problem came up again. I read that changing the function name to onsaveAs_clicked() will fix the problem as long as I add a connect to it, and it did! (Apparrently changing the naming convention will stop it from going to moc_ to automatically connect things) Everything is working perfectly now. Thanks so much for your help

    Just one more thing.. I'm trying to test out the background image for my photo-shopper buddy but when I try this->setStyleSheet("background-image: url(C:/Users/David/desktop/bg.png); "
    "background-position: top left;");
    it sets all of my stuff to it. (Buttons, textEdits, Labels included.) How would I separate the background from the rest of the widgets? (the image is 400, 200 as well)

    Code snippet:
    Qt Code:
    1. MinecraftSkinDownloader::MinecraftSkinDownloader(QWidget *parent) :
    2. QMainWindow(parent),
    3. ui(new Ui::MinecraftSkinDownloader)
    4. {
    5. ui->setupUi(this);
    6. this->setWindowTitle("Minecraft Skin Downloader");
    7. setFixedSize(400, 200);
    8. this->setStyleSheet("background-image: url(C:/Users/David/desktop/bg.png); " //<-- here it is
    9. "background-position: top left;");
    10. connect(ui->save, SIGNAL(clicked()), this, SLOT(onsaveAs_clicked()));
    11. }
    To copy to clipboard, switch view to plain text mode 

    Image of the app Before and After
    http://imgur.com/XWRBeXF

Similar Threads

  1. Downloading a file and saving in a path
    By StarRocks in forum Qt Programming
    Replies: 19
    Last Post: 3rd January 2013, 06:43
  2. Replies: 6
    Last Post: 3rd December 2012, 07:26
  3. Full path and filename of a Qt Plugin at runtime
    By be-noix in forum Qt Programming
    Replies: 2
    Last Post: 8th August 2011, 15:38
  4. Replies: 8
    Last Post: 17th October 2009, 08:10
  5. Replies: 2
    Last Post: 19th May 2009, 09:30

Tags for this Thread

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
  •  
Qt is a trademark of The Qt Company.