QT Foundation: 61 - HTTP Communication for Network Programming (QNetwork Request, QNetwork Reply, Network Access Manager)

I. Introduction of High Level Network Protocols

Qt network module provides some classes to implement high-level network protocols in OSI 7 layer network model, such as HTTP, FTP, SNMP, etc. These classes are mainly QNetworkRequest, QNetworkReply, Network Access Manager.

  • QNetworkRequest: Initiate network protocol requests through a URL address and also save the information of network requests. Currently, HTTP, FTP and local file URLs are supported for downloading or uploading.
  • Network Access Manager: Used to coordinate network operations. After QNetwork Request initiates a network request, Network Access Manager is responsible for sending network requests and creating network responses.
  • QNetwork Reply: Represents the correspondence of network requests. Network Access Manager creates a network response after sending a network request. QNetworkReply provides finished(), readyRead(), download progress () to monitor the execution of network responses and perform corresponding operations.

QNetworkReply is a subclass of QIODevice, so QNetworkReply supports streaming reads and writes as well as asynchronous or synchronous work.

Demonstration case

Step 1:

  • Create a project based on QMainWindow with the default class name. And design the interface
  • Enter a network file URL in the URL, set the download file save path, click the download button to download the file to the directory. Progress Bar indicates the progress of file download

Step 2:

  • Constructor
//Only the handwritten code is listed, and the default code of the system is omitted.
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QFile>
#include <QDir>
#include <QMessageBox>
#include <QUrl>
#include <QFileInfo>

class MainWindow : public QMainWindow
{
private:
    QNetworkAccessManager networkManager; //Network Management
    QNetworkReply *reply; //Network response
    QFile *downloadedFile; //Download saved temporary files    
private slots:
    //Custom slot function
    void on_finished();
    void on_readyRead();
    void on_downloadProgress(qint64 bytesRead,qint64 totalBytes);
};

Step 3:

  • Response function of default path button
// Create a temporary directory called temp under the current application directory
void MainWindow::on_btnDefaultPath_clicked()
{
    // Get the path of the current application
    QString curPath=QDir::currentPath();
    
    // Create a temporary directory temp under the current directory
    QDir dir(curPath);//Open the path of the current application
    QString sub="temp";
    dir.mkdir(sub);
    
    ui->editPath->setText(curPath+"/"+sub+"/");
}

Step 4:

  • Response function of download button
void MainWindow::on_btnDefaultPath_clicked()
{
    //Get the path of the current application
    QString curPath=QDir::currentPath();

    //Create a temporary directory temp under the current directory
    QDir dir(curPath);//Open the path to the current application
    QString sub="temp";
    dir.mkdir(sub);

    ui->editPath->setText(curPath+"/"+sub+"/");
}

void MainWindow::on_btnDownload_clicked()
{
    //Determine whether a URL has been entered
    QString urlSpec=ui->editURL->text().trimmed();
    if(urlSpec.isEmpty())
    {
        QMessageBox::information(this,QStringLiteral("error"),QStringLiteral("Please specify the files to download URL"));
        return;
    }

    //Convert the path to a URL variable to determine whether the input URL is incorrect
    QUrl newUrl=QUrl::fromUserInput(urlSpec);
    if(!newUrl.isValid())
    {
        QMessageBox::information(this,QStringLiteral("error"),QString(QStringLiteral("invalid URL: %1\n Error message:%2")).arg(urlSpec,newUrl.errorString()));
        return;
    }
    
    //Determine whether a directory has been opened to save downloaded files
    QString tempDir=ui->editPath->text().trimmed();
    if(tempDir.isEmpty())
    {
        QMessageBox::information(this,QStringLiteral("error"),QStringLiteral("Please specify a directory for downloading files to save."));
        return;
    }
    
    //If the file you want to download already exists, remove the original file first
    QString fullFileName=tempDir+newUrl.fileName();
    if(QFile::exists(fullFileName))
        QFile::remove(fullFileName);
    
    //Try to open the file to download
    downloadedFile=new QFile(fullFileName);
    if(!downloadedFile->open(QIODevice::WriteOnly))
    {
        QMessageBox::information(this,QStringLiteral("error"),QStringLiteral("Temporary file opening error"));
        return;
    }
    
    ui->btnDownload->setEnabled(false);
    
    //Publish a network request with QNetwork Access Manager, request to download the file represented by the URL address and create a network response
    reply=networkManager.get(QNetworkRequest(newUrl));
    //Correlation signal and slot
    connect(reply,SIGNAL(finished()),this,SLOT(on_finished()));
    connect(reply,SIGNAL(readyRead()),this,SLOT(on_readyRead()));
    connect(reply,SIGNAL(downloadProgress(qint64,qint64)),
            this,SLOT(on_downloadProgress(qint64,qint64)));
}

Step 5:

  • Three custom slot functions
void MainWindow::on_readyRead()
{
    // Read downloaded data
    downloadedFile->write(reply->readAll());
}
void MainWindow::on_downloadProgress(qint64 bytesRead,qint64 totalBytes)
{
    //Set the value of the progress bar
    ui->progressBar->setMaximum(totalBytes);
    ui->progressBar->setValue(bytesRead);
}
//After the end of the network request
void MainWindow::on_finished()
{
    QFileInfo fileInfo;
    fileInfo.setFile(downloadedFile->fileName());
    
    //Close the open network file and empty it
    downloadedFile->close();
    delete downloadedFile;
    downloadedFile=Q_NULLPTR;
    
    //Delete the network response and set it blank
    reply->deleteLater();
    reply=Q_NULLPTR;
    
    QMessageBox::information(this,QStringLiteral("Tips"),QStringLiteral("Download Successful"));

    //If you set up to open after the download is complete, open the file
    if(ui->checkOpen->isChecked())
    {
        //Call the default application software to open the downloaded file
        QDesktopServices::openUrl(QUrl::fromLocalFile(fileInfo.absoluteFilePath()));
        ui->btnDownload->setEnabled(true);
    }
}

Demonstration effect

Tags: network ftp Qt

Posted on Thu, 29 Aug 2019 04:09:25 -0700 by MarcB