简体   繁体   中英

Loading file over http

I'm new to QT and encountered the following problem.

Download returns an empty file:

QFile file("book.gif"); 
QHttp http; 
if (file.open(QIODevice::WriteOnly))
{ 
    http.setHost("www.geocities.com"); 
    http.get("/mslerm/images/qtbook.gif", &file); 
    http.close(); 
    file.close(); 
}

But if before closing http call messagebox - everything works fine:

QFile file("book.gif"); 
QHttp http; 
if (file.open(QIODevice::WriteOnly))
{ 
    http.setHost("www.geocities.com"); 
    http.get("/mslerm/images/qtbook.gif", &file);
    QMessageBox msgBox;
    msgBox.setText(http.errorString());
    msgBox.exec();
    http.close(); 
    file.close(); 
}

Any Ideas?

The problem is that the get() method is non blocking as stated by the documentation itself: Qhttp.get

One way to proceed is to connect the QHttp::dataReadProgress signal with a slot you develop where you process the received data from the QHttp object. Also remember that both QHttp and QFtp classes are now deprecated and the suggested classes to use are:

QNetworkAccessManager
QNetworkRequest
QNetworkReply

You should connect some callback to QHttp finished signal and close the file handler there. When you create a message box, the time from it popping up and you closing it is probably enough for the download to conclude, and then you close the file handler correctly. The key is that QMessageDialog::exec method is synchronous.

A message box spins an event loop in its exec() and allows QHttp's asynchronous processing to occur. An event loop must have a chance to run between starting a transfer and expecting any results.

Ideally, you should start the transfer and process the results in a slot connected to the requestFinished(...) signal of QHttp. After the transfer has been started, your code must return to the event loop.

As a quick hack, you can invoke QCoreApplication::processEvents(QEventLoop::AllEvents, time) , where time is the maximum number of milliseconds you expect your http transfer to take. This would be considered poor style and has negative consequences. For one, the code that starts the transfer can be reentered -- say, if you start the transfer in a button click slot, and the user clicks it again before the transfer is done.

You should adopt an asynchronous, event based programming style, where you have a chain of request/response functions: request functions start things that may take time, and response functions process the results. It may sound tedious, but it's the only way to produce responsive applications. Such code would normally reside in a QObject, and if all the processing is done by handling events or by signal/slot connections (but not direct calling of slots!), it can be trivially moved to another thread to further improve performance and lessen the impact of GUI thread pauses of mixed pedigree.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM