Results 1 to 17 of 17

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

  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

  17. #12
    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?

    Specify the class or object name the the style is to apply to, something like one of these:
    Qt Code:
    1. setStyleSheet("QMainWindow { background-image: url(C:/Users/David/desktop/bg.png); } "
    2.  
    3. setStyleSheet("QMainWindow#objectname { background-image: url(C:/Users/David/desktop/bg.png); } "
    To copy to clipboard, switch view to plain text mode 

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

    Salads (22nd January 2013)

  19. #13
    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?

    Two other things:

    - you don't need a new QNetworkManager for every request, just one will do fine (can handle multiple requests in parallel)
    - your code becomes the owner of the returned QNetworkReply so your code has to delete it. The easiest way to do that is to call reply->deleteLater() in the finished slot.

    Cheers,
    _

  20. #14
    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?

    So if I put the following code where QMainWindow function is it won't have to make a new one every time? Would this help with performance?
    EDIT: What if I set it as a public class definition? I have QNetworkAccessManager *manager; but the program crashes when I try to send the request. (When I press the pushButton originally set to send it)
    Qt Code:
    1. QNetworkAccessManager *manager = new QNetworkAccessManager(this);
    To copy to clipboard, switch view to plain text mode 

    Here's my complete .cpp file for reference:
    Qt Code:
    1. #include "minecraftskindownloader.h"
    2. #include "ui_minecraftskindownloader.h"
    3. #include "nouser.h"
    4. #include <QWidget>
    5. #include <QObject>
    6. #include <QtNetwork/QNetworkAccessManager>
    7. #include <QFileDialog>
    8. #include <QtNetwork/QNetworkRequest>
    9. #include <QDebug>
    10. #include <QUrl>
    11. #include <QFile>
    12. #include <QPixmap>
    13. #include <QMessageBox>
    14.  
    15. MinecraftSkinDownloader::MinecraftSkinDownloader(QWidget *parent) :
    16. QMainWindow(parent),
    17. ui(new Ui::MinecraftSkinDownloader)
    18. {
    19. ui->setupUi(this);
    20. this->setWindowTitle("Minecraft Skin Downloader");
    21. setFixedSize(400, 200);
    22. setStyleSheet("QMainWindow { background-image: url(:/bg.png); } ");
    23.  
    24. connect(ui->save, SIGNAL(clicked()), this, SLOT(onsaveAs_clicked()));
    25. }
    26.  
    27. MinecraftSkinDownloader::~MinecraftSkinDownloader()
    28. {
    29. delete ui;
    30. }
    31.  
    32. //http://s3.amazonaws.com/MinecraftSkins/USERNAMEHERE.png
    33.  
    34. void MinecraftSkinDownloader::on_pushButton_clicked()
    35. {
    36. QString prefix = "http://s3.amazonaws.com/MinecraftSkins/";
    37. QString usrl = prefix += ui->lineEdit->text() += ".png";
    38.  
    39. QNetworkAccessManager *manager = new QNetworkAccessManager(this);
    40. connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(slot_netwManagerFinished(QNetworkReply*)));
    41.  
    42. QUrl url(usrl);
    43. QNetworkRequest request(url);
    44.  
    45. manager->get(request);
    46.  
    47. }
    48.  
    49. void MinecraftSkinDownloader::slot_netwManagerFinished(QNetworkReply *reply)
    50. {
    51.  
    52. if (reply->error() != QNetworkReply::NoError)
    53. {
    54. qDebug() << "Error in" << reply->url() << ":" << reply->errorString();
    55. NoUser mDiag;
    56. mDiag.setModal(true);
    57. mDiag.exec();
    58. return;
    59. }
    60.  
    61. MinecraftSkinDownloader::pngData = reply->readAll();
    62. QPixmap pixmap;
    63. pixmap.loadFromData(MinecraftSkinDownloader::pngData);
    64. QPixmap scaled = pixmap.scaled(128,64,Qt::IgnoreAspectRatio, Qt::FastTransformation);
    65. ui->preview->show();
    66. ui->preview->setStyleSheet("QLabel { background-color: white; }");
    67. ui->preview->setPixmap(scaled);
    68. reply->deleteLater();
    69.  
    70. }
    71.  
    72. void MinecraftSkinDownloader::onsaveAs_clicked()
    73. {
    74. QString filename = QFileDialog::getSaveFileName(this, tr("Save Skin"), "C:/Users/", ("PNG Image (*.png)"));
    75.  
    76. QFile file(filename);
    77. file.open(QIODevice::WriteOnly);
    78. file.write(MinecraftSkinDownloader::pngData);
    79. file.close();
    80. }
    81.  
    82. void MinecraftSkinDownloader::on_pushButton_2_clicked()
    83. {
    84. ui->lineEdit->clear();
    85. ui->preview->hide();
    86. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by Salads; 23rd January 2013 at 07:35.

  21. #15
    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?

    Quote Originally Posted by Salads View Post
    [COLOR="#D3D3D3"]
    EDIT: What if I set it as a public class definition? I have QNetworkAccessManager *manager; but the program crashes when I try to send the request. (When I press the pushButton originally set to send it)
    I am not sure what you mean with that, the QNetworkManager creation in the code you posted seems to be unchanged.

    Btw, you'll also have to deleted the network reply in the error handling case

    Cheers,
    _

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

    Salads (23rd January 2013)

  23. #16
    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?

    Got the error part thanks

    I'll update my code:

    .h File:
    Qt Code:
    1. #ifndef MINECRAFTSKINDOWNLOADER_H
    2. #define MINECRAFTSKINDOWNLOADER_H
    3.  
    4. #include <QMainWindow>
    5. #include <QtNetwork/QNetworkReply>
    6. #include <QtNetwork/QNetworkAccessManager>
    7.  
    8. namespace Ui {
    9. class MinecraftSkinDownloader;
    10. }
    11.  
    12. class MinecraftSkinDownloader : public QMainWindow
    13. {
    14. Q_OBJECT
    15.  
    16. public:
    17. explicit MinecraftSkinDownloader(QWidget *parent = 0);
    18. ~MinecraftSkinDownloader();
    19. QByteArray pngData;
    20. QNetworkAccessManager *manager;
    21.  
    22. private slots:
    23.  
    24. void slot_netwManagerFinished(QNetworkReply *reply);
    25.  
    26. void onsaveAs_clicked();
    27.  
    28. void on_clear_clicked();
    29.  
    30. void on_pushButton_clicked();
    31.  
    32. private:
    33. Ui::MinecraftSkinDownloader *ui;
    34.  
    35.  
    36. };
    37.  
    38. #endif // MINECRAFTSKINDOWNLOADER_H
    To copy to clipboard, switch view to plain text mode 

    .cpp File
    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. #include <QPixmap>
    12. #include <QMessageBox>
    13.  
    14. MinecraftSkinDownloader::MinecraftSkinDownloader(QWidget *parent) :
    15. QMainWindow(parent),
    16. ui(new Ui::MinecraftSkinDownloader)
    17. {
    18. ui->setupUi(this);
    19. this->setWindowTitle("Minecraft Skin Downloader");
    20. QIcon icon(":/ico");
    21. setWindowIcon(icon);
    22. setFixedSize(400, 200);
    23. setStyleSheet("QMainWindow { background-image: url(:/bg.png); } ");
    24.  
    25. connect(ui->save, SIGNAL(clicked()), this, SLOT(onsaveAs_clicked()));
    26.  
    27. }
    28.  
    29. MinecraftSkinDownloader::~MinecraftSkinDownloader()
    30. {
    31. delete ui;
    32. }
    33.  
    34. //http://s3.amazonaws.com/MinecraftSkins/USERNAMEHERE.png
    35.  
    36. void MinecraftSkinDownloader::on_pushButton_clicked()
    37. {
    38. QString prefix = "http://s3.amazonaws.com/MinecraftSkins/";
    39. QString usrl = prefix += ui->lineEdit->text() += ".png";
    40.  
    41. //QNetworkAccessManager *manager = new QNetworkAccessManager(this);
    42. connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(slot_netwManagerFinished(QNetworkReply*)));
    43.  
    44. QUrl url(usrl);
    45. QNetworkRequest request(url);
    46.  
    47. manager->get(request);
    48.  
    49. }
    50.  
    51. void MinecraftSkinDownloader::slot_netwManagerFinished(QNetworkReply *reply)
    52. {
    53.  
    54. if (reply->error() != QNetworkReply::NoError)
    55. {
    56. qDebug() << "Error in" << reply->url() << ":" << reply->errorString();
    57. QPixmap noUsr(":/voidUser.png"); // Void User path
    58. ui->preview->show();
    59. ui->preview->setStyleSheet("background: transparent;");
    60. ui->preview->setPixmap(noUsr);
    61. reply->deleteLater();
    62. return;
    63. }
    64.  
    65. pngData = reply->readAll();
    66. QPixmap pixmap;
    67. pixmap.loadFromData(pngData);
    68. QPixmap scaled = pixmap.scaled(128,64,Qt::IgnoreAspectRatio, Qt::FastTransformation);
    69. ui->preview->show();
    70. ui->preview->setStyleSheet("QLabel { background-color: white; }");
    71. ui->preview->setPixmap(scaled);
    72. reply->deleteLater();
    73.  
    74. }
    75.  
    76. void MinecraftSkinDownloader::onsaveAs_clicked()
    77. {
    78. if(pngData.isEmpty())
    79. {
    80. ui->preview->show();
    81. QPixmap error(":/noSaveData.png");
    82. ui->preview->setPixmap(error);
    83. return;
    84. }
    85.  
    86. QString filename = QFileDialog::getSaveFileName(this, tr("Save Skin"), "C:/Users/", ("PNG Image (*.png)"));
    87.  
    88. QFile file(filename);
    89. file.open(QIODevice::WriteOnly);
    90. file.write(pngData);
    91. file.close();
    92. }
    93.  
    94. void MinecraftSkinDownloader::on_clear_clicked()
    95. {
    96. pngData.clear();
    97. ui->preview->setStyleSheet("background: transparent;");
    98. ui->lineEdit->clear();
    99. ui->preview->hide();
    100. return;
    101. }
    To copy to clipboard, switch view to plain text mode 

    It crashes the moment I press that on_pushButton_clicked(), and doesn't even get to display the error message (voidUser.png) when I leave it blank. Same thing happens when I put a valid username in there too.

  24. #17
    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 ran the program in your debugger you would know exactly which line your program was crashing on (probably 42, maybe 47), which is more useful than the "somewhere in on_pushButton_clicked()" level of information you have now.

    You have made a pointer to QNetworkAccessManager member variable but you never initialise that pointer. When you subsequently use it... BOOM! You need to move the equivalent of line 41 (also 42) into the constructor. A good habit to get into is: any time you add a member variable to a class immediately add an initialisation of the variable into the constructor. In the case of pointers that can be setting it to 0 or allocating a new object; either way it forces you to think about where it should be set.

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

    Salads (31st January 2013)

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
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.