Results 1 to 11 of 11

Thread: NEED HELP: How to download file without breaking function

  1. #1
    Join Date
    Feb 2008
    Posts
    153
    Thanks
    40
    Thanked 8 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Question NEED HELP: How to download file without breaking function

    Ok, so this is my situation: I need to download a file from a server, and when it's done, read it or open it using QFile, QIODevice, etc. I saw the tutorial in the documentation, but it is simple and doesn't show how to do something with the file afterwards. The problem is, get() returns immediately and any attempt and reading the file afterwards results in a blank. Following the tutorial involves breaking the function, creating a done() signal, and connecting it to a function which will read the file/download a new one.

    WHAT I AM ASKING: How do I download a file without having to exit the current function? Do I need to make a CPU-intensive while() loop which will continiously check if the download is done, or is there a different way which I have not found out yet?

    If you're wondering why I need this, it's to create and updater which will check the server for a new version of the program (by downloading a file with version info, any alternative ways to transmit such small information will be helpful), then comparing it to the current version, and finally downloading the latest version.

    Again, I'm using QHttp, and I DON'T want to use slots because I would end up with a bunch of confusing signals and slots leading to the next step. Instead, I want a clean "downloadFile()" function which returns a pointer to the file or a bool if it succeeds and only after the file is downloaded, i.e. redo the get() function to return only after it's done downloading.

    Anyways, thanks in advance =] - codeslicer

  2. #2
    Join Date
    Jun 2007
    Posts
    12
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: NEED HELP: How to download file without breaking function

    well, AFAIK, you will need to use slots.

    You need to know that all your data has been received before trying to read it, that's why you need to wait for correct signal to be emitted.

    If you do something like:
    Qt Code:
    1. http->setHost("yourhost");
    2. http->get("yourfile","your QIODevice");
    To copy to clipboard, switch view to plain text mode 

    Then you will need to connect the done() function with a slot that will read the data stored in your device and decide whether to read another file, download that version or whatever you want to do.

  3. #3
    Join Date
    Feb 2008
    Posts
    153
    Thanks
    40
    Thanked 8 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Arrow Re: NEED HELP: How to download file without breaking function

    Ok thanks... but it's not possible to make a while() loop that will continiously check for some isDone() thing? Having millions of slots all connected to each other is confusing. Thanks for answering though

  4. #4
    Join Date
    Jun 2007
    Posts
    12
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: NEED HELP: How to download file without breaking function

    But you are not going to have millions of slots. Just one slot. If you name your slot correctly, it will be quite straight forward to undestand the code.

    IMHO, trying to solve this with a while loop is much more complex and requires more code lines than connecting the done() signal with a httpCommandFinished() slot. After all, you want to keep it simple, isn't it?

  5. #5
    Join Date
    Feb 2008
    Posts
    153
    Thanks
    40
    Thanked 8 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Lightbulb Can't create self-contained downloadFile() function then?

    Ok... so I have to do this:

    1.) Create a slot for the updateButton clicked() signal
    2.) In that slot make a QHttp object called getVersionInfo and use get() to retrieve the version file. Exit the slot and enter the event loop.
    3.) Connect the done() signal from getVersionInfo to a slot which will read the file, and determine if downloading the latest version is necessary or not
    4.) If so, create a second QHttp object called getNewUpdate and again use get() to retrieve the installer. Again exit the slot and enter the event loop.
    5.) Connect the done() signal from getNewUpdate object to another slot which will execute the installer, terminate the program, etc

    If that is the only possible way to download a file, do something with it, and continue with other commands (In other words that it isn't possible to just create a downloadFile() function which will return only after the file is download, or else return an error message) then how would I go into implementing a downloadFile class?

    Sorry, I'm a bit new to Qt and C++ (Only ~1/2 year) and used to the noob-friendly enviroment of Visual Basic .NET. The reason I quit was that it wasn't portable, required a huge framework, and wasn't *nix friendly.

    If I get could some help, I would be very grateful. Thanks in advance - codeslicer

  6. #6
    Join Date
    Aug 2006
    Posts
    250
    Thanks
    19
    Thanked 49 Times in 36 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Can't create self-contained downloadFile() function then?

    An alternative is to use http://www.libqxt.org/docs/classQxtSignalWaiter.html from the Qxt library, which should allow you to do this without multiple slots.

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

    codeslicer (5th February 2008)

  8. #7
    Join Date
    Feb 2008
    Posts
    153
    Thanks
    40
    Thanked 8 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Question Doesn't work :(

    Ok... I tried it but I get lots of different errors =[ I guess I have to have multiple blocks of signals and slots that wait for each other What about while() loops though. Could those be used instead?

    Also, can QFile read a file from the internet, for example without downloading it to a tmp folder then reading it from there, but instead somehow directly reading it from the server?
    Last edited by codeslicer; 5th February 2008 at 01:48. Reason: Doesn't work

  9. #8
    Join Date
    Jun 2007
    Posts
    12
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: NEED HELP: How to download file without breaking function

    You can read the file from internet using Qhttp::get() function. The second parameter is the QIODevice where you want to write the info, and QFile is an IODevice

    I never used http protocol, but, can't you request the current version number using this protocol and if the version mismatch, download the file?

    I've read the doc a bit more and seems that you just need one slot. Let's call it HttpRequestFinished().

    Connect the requestFinished() signal with this slot. Once the file is loaded, this signal will be emited and you can do whatever checks/operations you may want.

    this is a draft example
    Qt Code:
    1. connect(http,SIGNAL(requestFinished(int,bool)),this,SLOT(httpRequestFinished(int, bool)));
    2. http->setHost("yourhost");
    3. id1 = http->get("versionInfo");
    4. ... //whatever code you have
    5. void httpRequestFinished(int id, bool error){
    6. //check for errors if you want
    7. if (id == id1){
    8. //check here if the version number is right, if not, do id2 = http->get("thefile",yourQFile)
    9. }
    10. if (id == id2){
    11. //you got your file and it's in your QFile.. do what you have to do with it
    12. }
    13. }
    To copy to clipboard, switch view to plain text mode 

    This should work, and means using just one slot. Connected to the right signal.

    Check QHttp doc to find out how you could optimize the code in your case.

    My 2 cents.

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

    codeslicer (6th February 2008)

  11. #9
    Join Date
    Feb 2008
    Posts
    153
    Thanks
    40
    Thanked 8 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Red face Re: NEED HELP: How to download file without breaking function

    Ok thanks. First I'm gonna try to do the while loop so I can just make a downloadFile() function, but if that doesn't work, I'll try slots like you said. Thanks =]

  12. #10
    Join Date
    Mar 2006
    Posts
    140
    Thanks
    8
    Thanked 4 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: NEED HELP: How to download file without breaking function

    1.) Create a slot for the updateButton clicked() signal
    2.) In that slot make a QHttp object called getVersionInfo and use get() to retrieve the version file. Exit the slot and enter the event loop.
    3.) Connect the done() signal from getVersionInfo to a slot which will read the file, and determine if downloading the latest version is necessary or not
    4.) If so, create a second QHttp object called getNewUpdate and again use get() to retrieve the installer. Again exit the slot and enter the event loop.
    5.) Connect the done() signal from getNewUpdate object to another slot which will execute the installer, terminate the program, etc
    No.

    1.) Create a slot for the updateButton clicked() signal
    2.) In that slot make a QHttp object called getVersionInfo, connect requestFinished(int, bool) signal to some slot you define.
    3.) Set the host and user / pass if needed.
    4.) Use get() passing in file uri to download. I also recommend passing in an opened QFile object as the second argument, then the request will automagically save the file data for you. (I don't understand why you're talking about event loops at this point). Assign the return integer value to a member variable which you can compare in your requestFinished(int, bool) receiver slot, say m_fileGetId.
    The way the QHttp works is you can feed in loads of requests and they are processed in a queue which QHttp manages internally. At some point in future the requestFinished signal will emit passing the id return for the request as the first parameter, so you need to do something like:
    Qt Code:
    1. void Downloader::fileDownloadRequestFinished(int id, bool error)
    2. {
    3. if(id == m_fileGetId)
    4. {
    5. m_file.close();
    6.  
    7. }
    8. }
    To copy to clipboard, switch view to plain text mode 
    Bear in mind that that m_http->setHost(...) call actually returns and id and so do the user / pass setting functions so they count as requests which will emit the signal which is why you need to keep track of the id of the FILE request.

    "How do I download a file without having to exit the current function? Do I need to make a CPU-intensive while() loop which will continiously check if the download is done, or is there a different way which I have not found out yet?"
    Let it return, what's the problem, the download will be happening in the background and when the above slot is called and the id matches the get id, then you know that the download is complete, so open it. Here's an extended version of the above example:
    Qt Code:
    1. void Downloader::fileDownloadRequestFinished(int id, bool error)
    2. {
    3. if(id == m_fileGetId)
    4. {
    5. m_file.flush();
    6. m_file.close(); // Flushes and closes the file ready for opening.
    7.  
    8. if(m_file.open(QIODevice::ReadOnly))
    9. {
    10. // load the content
    11.  
    12. m_file.close();
    13. }
    14.  
    15. }
    16. }
    To copy to clipboard, switch view to plain text mode 

    You need to realise that signal / slot connections make your job much simpler, dont' be afraid of them.

    The unfortunate thing about QHttp is that occasionally you may want to do job synchronously, but it's not supported by QHttp, but hey, it's a workable situation.
    If you want to hold up your ui so nothing can be done until the file is downloaded, you can put a progressbar on your ui or modal dialog and do this:
    Qt Code:
    1. connect(m_http, SIGNAL(dataReadProgress(int, int)), this, SLOT(SetProgress(int, int)));
    2.  
    3. void Downloader::SetProgress(int bytesRead, int totalBytes)
    4. {
    5. ui.progressBar->setMaximum( totalBytes );
    6. ui.progressBar->setValue( bytesRead );
    7. }
    To copy to clipboard, switch view to plain text mode 

    If you do the progressbar in a modal dialog, then guess what, you need another slot. You could define a slot on the modal progress ui which subscribes to the progressbars valueChanged ( int value ) signal, which then analyses the value of the progressbar. If it's at 100% (current value == max) then calls this->close().
    There are other ways of approaching it but it's up to you.

    BUT, if you insist on a tight while loop, then put some kind of thread "sleep for 100 ms" call in so you don't destroy the PC's performance.

  13. #11
    Join Date
    Mar 2006
    Posts
    140
    Thanks
    8
    Thanked 4 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: NEED HELP: How to download file without breaking function

    Something else you could also do is start a new thread and get it to do the get request, but setup in a QMutex and QWaitCondition in advance say m_getMutex and m_waitCond, then just after starting the thread, call m_waitCond( &m_getMutex). In your get request thread once the requestFinished slot is called and you've closed you QFile object, call m_waitCond.wakeAll() then you main thread will only continue once the download is done.

Similar Threads

  1. QPSQL driver in windows
    By brevleq in forum Installation and Deployment
    Replies: 31
    Last Post: 14th December 2007, 12:57
  2. how to add static library into qmake
    By Namrata in forum Qt Tools
    Replies: 1
    Last Post: 20th November 2007, 17:33
  3. Replies: 3
    Last Post: 18th October 2007, 18:07
  4. KDE/QWT doubt on debian sarge
    By hildebrand in forum KDE Forum
    Replies: 13
    Last Post: 25th April 2007, 06:13
  5. use qpsql
    By raphaelf in forum Installation and Deployment
    Replies: 34
    Last Post: 22nd August 2006, 12:52

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.