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:
void Downloader::fileDownloadRequestFinished(int id, bool error)
{
if(id == m_fileGetId)
{
m_file.close();
}
}
void Downloader::fileDownloadRequestFinished(int id, bool error)
{
if(id == m_fileGetId)
{
m_file.close();
}
}
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:
void Downloader::fileDownloadRequestFinished(int id, bool error)
{
if(id == m_fileGetId)
{
m_file.flush();
m_file.close(); // Flushes and closes the file ready for opening.
{
// load the content
m_file.close();
}
}
}
void Downloader::fileDownloadRequestFinished(int id, bool error)
{
if(id == m_fileGetId)
{
m_file.flush();
m_file.close(); // Flushes and closes the file ready for opening.
if(m_file.open(QIODevice::ReadOnly))
{
// load the content
m_file.close();
}
}
}
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:
connect(m_http, SIGNAL(dataReadProgress(int, int)), this, SLOT(SetProgress(int, int)));
void Downloader::SetProgress(int bytesRead, int totalBytes)
{
ui.progressBar->setMaximum( totalBytes );
ui.progressBar->setValue( bytesRead );
}
connect(m_http, SIGNAL(dataReadProgress(int, int)), this, SLOT(SetProgress(int, int)));
void Downloader::SetProgress(int bytesRead, int totalBytes)
{
ui.progressBar->setMaximum( totalBytes );
ui.progressBar->setValue( bytesRead );
}
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.
Bookmarks