qt 之http學習


在Qt網絡編程中,需要用到協議,即HTTP。它是超文本傳輸協議,它是一種文件傳輸協議。

新建工程名為“http”,然后選中QtNetwork模塊,最后Base class選擇QWidget。注意:如果新建工程時沒有添加QtNetwork模塊,那么就要手動在工程文件.pro中添加代碼

  1. QT += network  

表明我們使用了網絡模塊。

2.我們在widget.ui文件中添加一個 Text Browser ,如下圖。

Qt網絡之HTTP編程

 

實現的代碼如下:

widget.h文件:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QNetworkAccessManager>
#include <qtextcodec.h>
#include <QNetworkReply>
namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private:
    Ui::Widget *ui;
    QNetworkAccessManager* manager;
private slots:
    void replyFinished(QNetworkReply *);
};

#endif // WIDGET_H

widget.cpp文件:

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    manager = new QNetworkAccessManager(this);
    connect(manager,SIGNAL(finished(QNetworkReply*)),  //關聯信號和槽
                this,SLOT(replyFinished(QNetworkReply*)));
    manager->get(QNetworkRequest(QUrl("http://www.baidu.com"))); //發送請求
}

Widget::~Widget()
{
    delete ui;
}
void Widget::replyFinished(QNetworkReply *reply)  //當回復結束后
{
    QTextCodec *codec = QTextCodec::codecForName("utf8");
    //使用utf8編碼,這樣才可以顯示中文
    QString all = codec->toUnicode(reply->readAll());
    ui->textBrowser->setText(all);
    reply->deleteLater();   //最后要釋放reply對象
}

 

代碼分析。

上面實現了最簡單的應用HTTP協議下載網頁的程序。QNetworkAccessManager類用於發送網絡請求和接受回復,具體的,它是用QNetworkRequest類來管理請求,QNetworkReply類進行接收回復,並對數據進行處理。

在上面的代碼中,我們使用了下面的代碼來發送請求:

  1. manager->get(QNetworkRequest(QUrl(“http://www.yafeilinux.com”))); 

它返回一個QNetworkReply對象,這個下面再講。我們只需知道只要發送請求成功,它就會下載數據。而當數據下載完成后,manager會發出finished()信號,我們對它進行了關聯:

  1. connect(manager,SIGNAL(finished(QNetworkReply*)),  
  2.             this,SLOT(replyFinished(QNetworkReply*))); 

也就是說,當下載數據結束時,就會執行replyFinished()函數。在這個函數中我們對接收的數據進行處理:

  1. QTextCodec *codec = QTextCodec::codecForName(“utf8″); 
  2. QString all = codec->toUnicode(reply->readAll()); 
  3. ui->textBrowser->setText(all); 

這里,為了能顯示下載的網頁中的中文,我們使用了QTextCodec 類對象,應用utf8編碼。

使用reply->readAll()函數就可以將下載的所有數據讀出。然后,我們在textBrowser中將數據顯示出來。當reply對象已經完成了它的功能時,我們需要將它釋放,就是最后一條代碼:

  1. reply->deleteLater(); 
 
二、功能擴展
開始我們先讓進度條隱藏。當我們在Line 
Edit中輸入下載地址,點擊下載按鈕后,我們應用輸入的下載地址,獲得文件名,在磁盤上新建一個文件,用於保存下載的數據,然后進行鏈接,並顯示進度
條。在下載過程中,我們將每次獲得的數據都寫入文件中,並更新進度條,在接收完文件后,我們重新隱藏進度條,並做一些清理工作。

 

 
        
通過上面的例子可以看到,Qt中編寫基於HTTP協議的程序是十分簡單的,只有十幾行代碼。不過,一般我們下載文件都想要看到下載進度。下面我們就更改上面的程序,讓它可以下載任意的文件,並且顯示下載進度。

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QNetworkAccessManager>
#include <qtextcodec.h>
#include <QNetworkReply>
#include <QFile>
#include <QFileInfo>
#include <QDebug>
namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
    void startRequest(QUrl url); //請求鏈接
protected:
    //void changeEvent(QEvent *e);

private:
    Ui::Widget *ui;
    QNetworkAccessManager* manager;
    QNetworkReply *reply;
    QUrl url; //存儲網絡地址
    QFile *file;//存儲文件
private slots:
    void on_download_clicked();
    void httpFinshed();
    void httpReadyRead();
    void updataDataReadProcess(qint64,qint64 );//更新進度條
};

#endif // WIDGET_H

3.widget.cpp文件

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    manager = new QNetworkAccessManager(this);
    ui->progressBar->hide();
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_download_clicked()
{
    url=ui->lineEdit->text();
    //獲取在界面輸入的url地址
    QFileInfo info(url.path());
    QString filename(info.fileName());
    //獲取文件名
    if(filename.isEmpty()) filename="index.html";
    file=new QFile(filename);
    if(!file->open(QIODevice::WriteOnly))
    {
        //qDebug<<"file open errror";
        delete file;
        file=0;
        return;
    }
    startRequest(url);//進行鏈接請求
    ui->progressBar->setValue(0);//進度條的值設為零
    ui->progressBar->show(); //顯示進度條
}
void Widget::startRequest(QUrl url)  //鏈接請求
{
    reply = manager->get(QNetworkRequest(url));
    //下面關聯信號和槽
    connect(reply,SIGNAL(finished()),this,SLOT(httpFinished()));
    //下載完成后
    connect(reply,SIGNAL(readyRead()),this,SLOT(httpReadyRead()));
    //有可用數據時
    connect(reply,SIGNAL(downloadProgress(qint64,qint64)),
            this,SLOT(updateDataReadProgress(qint64,qint64)));
    //更新進度條
}
void Widget::httpReadyRead()   //有可用數據
{
    if (file) file->write(reply->readAll());  //如果文件存在,則寫入文件
}
void Widget::updataDataReadProcess(qint64 bytesRead, qint64 totalBytes)
 {
    ui->progressBar->setMaximum(totalBytes); //最大值
    ui->progressBar->setValue(bytesRead);  //當前值
}
void Widget::httpFinshed()  //完成下載
{
    ui->progressBar->hide();
    file->flush();
    file->close();
    reply->deleteLater();
    reply = 0;
    delete file;
    file = 0;
}

我們HTTP應用的內容就講到這里,可以看到它是很容易的,也不需要你了解太多的HTTP的原理知識。關於相關的類的其他使用,你可以查看其幫助










免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM