天天看點

windows下vs2017和Qt5.9.7環境下使用QFtp一、環境搭建QFtp檔案的拷貝使用 二、使用方法

現在Qt主推使用 QNetworkAccessManager 可以實作 Ftp 的上傳/下載下傳功能(參考:Qt之FTP上傳/下載下傳),但有些原本 QFtp 有的功能 QNetworkAccessManager 卻沒有提供,例如:list、cd、remove、mkdir、rmdir、rename 等。這種情況下,就不得不使用 QFtp,值得慶幸的是 QFtp 一直在維護,隻需要下載下傳源碼自行編譯即可使用。而我恰好需要使用到list。是以需要重新編譯QFtp。

一、環境搭建

QFtp

下載下傳

從 GitHub 下載下傳 QFtp:

https://github.com/qt/qtftp
windows下vs2017和Qt5.9.7環境下使用QFtp一、環境搭建QFtp檔案的拷貝使用 二、使用方法

配置

注意:第一次使用CONFIG -= static   CONFIG+=shared

第二次使用CONFIG += static   CONFIG-=shared

編譯後的庫才會齊全。

該庫的連結為:https://download.csdn.net/download/weixin_41882459/12104260

在pro檔案中完成此兩項配置

windows下vs2017和Qt5.9.7環境下使用QFtp一、環境搭建QFtp檔案的拷貝使用 二、使用方法
windows下vs2017和Qt5.9.7環境下使用QFtp一、環境搭建QFtp檔案的拷貝使用 二、使用方法

檔案的拷貝

目錄下生成的*.dll動态庫檔案(Qt5Ftp.dll、Qt5Ftpd.dll)複制到C:\Qt\Qt5.10.1\5.10.1\msvc2015\bin目錄下。

目錄下生成的*.lib和*.prl靜态庫檔案複制到 C:\Qt\Qt5.10.1\5.10.1\msvc2015\lib

目錄下的qftp.h和qurlinfo.h複制到 C:\Qt\Qt5.10.1\5.10.1\msvc2015\include\QtNetwork目錄下。

在C:\Qt\Qt5.10.1\5.10.1\msvc2015\include\QtNetwork目錄中建立一個沒有字尾名的QFtp檔案

然後用記事本寫入#include ”qftp.h”

使用

在 pro 中添加 QFtp 庫:

CONFIG(debug, debug|release) {

    LIBS += -lQt5Ftpd

} else {

    LIBS += -lQt5Ftp

}

windows下vs2017和Qt5.9.7環境下使用QFtp一、環境搭建QFtp檔案的拷貝使用 二、使用方法

例如,如果要連接配接并登入到 FTP 伺服器,這是簡單的實作:

#include <QFtp>

// ...

QFtp *ftp = new QFtp(parent);

ftp->connectToHost("192.168.***.***", 2121);  // 主機:192.168.***.*** 端口号:2121  

ftp->login("dell-T", "123456");  // 使用者名:dell-T 密碼:123456

// ...

 二、使用方法

使用流程

1、連接配接ftp到伺服器

2、下載下傳或上傳

3、關閉

主要代碼如下

ftp連接配接到伺服器

//ftp用戶端連接配接
    ftpClient=new QFtp(this);
    // 當每條指令開始執行時發出相應的信号
    connect(ftpClient,SIGNAL(commandStarted(int)),this,SLOT(ftpCommandStarted(int)));
    connect(ftpClient,SIGNAL(commandFinished(int,bool)),this,SLOT(ftpCommandFinished(int,bool)));
    connect(ftpClient,SIGNAL(listInfo(QUrlInfo)),this,SLOT(addToList(QUrlInfo)));
    connect(ftpClient,SIGNAL(dataTransferProgress(qint64,qint64)),this,SLOT(updateDataTransferProgress(qint64,qint64)));
    connect(ftpClient,SIGNAL(stateChanged(int)),this,SLOT(ftpStateChanged(int)));
    ftpClient->setTransferMode(QFtp::Active);
    ftpClient->connectToHost(ui->FTPServerLineEdit->text(),ui->ftpServerPortSpinBox->value());
    ftpClient->login(ui->FTPIDLineEdit->text(),ui->FTPPasswordLineEdit->text());
           

ftp下載下傳

void MainWindow::dealFtpDownloadSignal()
{
    QFileInfo fi(globalCurrentFile);
    ui->downLoadLabel->setText(fi.fileName()+"下載下傳進度");
    ftpClient->get(fi.fileName(),globalCurrentDownloadFile);
}
           

下載下傳進度條更新

void MainWindow::updateDataTransferProgress(qint64 bytesReceived, qint64 bytesTotal)
{
    ui->progressBar->setMaximum(bytesTotal);
    ui->progressBar->setValue(bytesReceived);
}
           

ftp狀态改變

void MainWindow::ftpStateChanged(int state)
{
    switch (state) {
    case QFtp::Unconnected: {
        setInsertTextColor(Qt::red);
        ui->infoTextEdit->append(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss zzz")+tr(":沒有連接配接到主機"));
        break;
    }
    case QFtp::HostLookup: {
        setInsertTextColor(Qt::black);
        ui->infoTextEdit->append(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss zzz")+tr(":正在進行主機名查找..."));
        break;
    }
    case QFtp::Connecting: {
        setInsertTextColor(Qt::black);
        ui->infoTextEdit->append(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss zzz")+tr(":正在嘗試連接配接到主機..."));
        break;
    }
    case QFtp::Connected: {
        setInsertTextColor(Qt::black);
        ui->infoTextEdit->append(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss zzz")+tr(":已實作與主機的連接配接"));
        break;
    }
    case QFtp::LoggedIn: {
        setInsertTextColor(Qt::black);
        ui->infoTextEdit->append(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss zzz")+tr(":已實作連接配接和使用者登入"));
        break;
    }
    case QFtp::Closing: {
        setInsertTextColor(Qt::black);
        ui->infoTextEdit->append(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss zzz")+tr(":連接配接正在關閉"));
        break;
    }
    default:
        break;
    }
}
           

ftp指令啟動

void MainWindow::ftpCommandStarted(int)
{
    if(ftpClient->currentCommand() == QFtp::ConnectToHost)
    {
        setInsertTextColor(Qt::black);
        ui->infoTextEdit->append(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss zzz")+tr(":正在連接配接到伺服器..."));
    }
    if (ftpClient->currentCommand() == QFtp::Login)
    {
        setInsertTextColor(Qt::black);
        ui->infoTextEdit->append(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss zzz")+tr(":正在登入..."));

    }
    if (ftpClient->currentCommand() == QFtp::Get)
    {
        setInsertTextColor(Qt::black);
        QFileInfo fi(globalCurrentFile);
        ui->infoTextEdit->append(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss zzz")+":"+fi.fileName()+tr(":正在下載下傳..."));
    }
    else if (ftpClient->currentCommand() == QFtp::Close)
    {
        setInsertTextColor(Qt::black);
        ui->infoTextEdit->append(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss zzz")+tr(":正在關閉連接配接..."));
    }
}
           

添加檔案或檔案夾至TreeWidget

void MainWindow::addToList(const QUrlInfo &urlInfo)
{
    QTreeWidgetItem *item = new QTreeWidgetItem;
    item->setText(0, urlInfo.name());
    item->setText(1, QString::number(urlInfo.size()/1024));//KB
    item->setText(2, urlInfo.owner());
    item->setText(3, urlInfo.group());
    item->setText(4, urlInfo.lastModified().toString("yyyy-MM-dd "));
    //擷取檔案資訊并存儲
    tagUrlInfo.allFileNamesList<<urlInfo.name();
    tagUrlInfo.allFilesSizeList<<QString::number(urlInfo.size()/1024);
    tagUrlInfo.allFilesOwnerList<<urlInfo.owner();
    tagUrlInfo.allFilesGroupList<<urlInfo.group();
    tagUrlInfo.allFilesLastModifiedList<<urlInfo.lastModified().toString("yyyy-MM-dd ");

    QPixmap pixmap(urlInfo.isDir() ? "./res/dir.png" : "./res/file.png");
    item->setIcon(0, pixmap);
    isDirectory[urlInfo.name()] = urlInfo.isDir();
    //存儲該路徑是否為目錄的資訊
    ui->fileTreeWidget->setHeaderLabels(QStringList()<<"檔案"<<"檔案大小(KB)"<<"所有者"<<"所屬組"<<"修改日期");
    ui->fileTreeWidget->addTopLevelItem(item);
    if (!ui->fileTreeWidget->currentItem())
    {
        ui->fileTreeWidget->setCurrentItem(ui->fileTreeWidget->topLevelItem(0));
        ui->fileTreeWidget->setEnabled(true);
    }
}
           

ftp指令完成。

void MainWindow::ftpCommandFinished(int,bool error)
{
    if(ftpClient->currentCommand() == QFtp::ConnectToHost)
    {
        if(error)
        {
            setInsertTextColor(Qt::red);
            ui->infoTextEdit->append(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss zzz")+tr(":連接配接伺服器出現錯誤:%1")
                                      .arg(ftpClient->errorString()));

        }
        else
        {
            setInsertTextColor(Qt::black);
            ui->infoTextEdit->append(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss zzz")+tr(":連接配接到伺服器成功"));

        }
    }
    if (ftpClient->currentCommand() == QFtp::Login)
    {
        if(error)
        {
            setInsertTextColor(Qt::red);
            ui->infoTextEdit->append(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss zzz")+tr(":登入出現錯誤:%1")
                                      .arg(ftpClient->errorString()));

        }
        else
        {
            setInsertTextColor(Qt::black);
            ui->infoTextEdit->append(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss zzz")+tr(":登入成功"));

            //儲存至配置檔案
            rwiniFile=new RWINIFile();
            rwiniFile->writeIni(filePath,"FTPServer","FTPServer",ui->FTPServerLineEdit->text());
            rwiniFile->writeIni(filePath,"FTPServer","FTPAccount",ui->FTPIDLineEdit->text());
            rwiniFile->writeIni(filePath,"FTPServer","FTPPort",QString::number(ui->ftpServerPortSpinBox->value()));
            delete rwiniFile;
            rwiniFile=NULL;
            ftpClient->list();//發射listInfo()信号,顯示檔案清單
        }
    }
    if(ftpClient->currentCommand() == QFtp::List)
    {
        if(isDirectory.isEmpty())
        {
            //如果目錄為空,顯示"empty"
            ui->fileTreeWidget->addTopLevelItem(new QTreeWidgetItem(QStringList()<<tr("<empty>")));
            ui->fileTreeWidget->setEnabled(false);
            //            QMessageBox::information(this,"資訊提示!","該目錄為空!");
        }
    }
    if (ftpClient->currentCommand() == QFtp::Get)
    {
        QFileInfo fi(globalCurrentFile);
        if(error)
        {
            setInsertTextColor(Qt::red);
            ui->infoTextEdit->append(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss zzz")+":"+fi.fileName()+tr(":下載下傳出現錯誤:%1")
                                      .arg(ftpClient->errorString()));
        }
        else
        {
            setInsertTextColor(Qt::black);
            //此處需要關閉檔案
            ui->infoTextEdit->append(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss zzz")+":"+fi.fileName()+tr(":已經完成下載下傳"));

            globalCurrentDownloadFile->close();
            //            globalCurrentDownloadFile->deleteLater();
            //下面内容需要加鎖
            ftpT->mutex->lock();
            fileCount++;
            isFinished=true;
            ftpT->mutex->unlock();
        }
    }
    else if (ftpClient->currentCommand() == QFtp::Close)
    {
        setInsertTextColor(Qt::black);
        ui->infoTextEdit->append(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss zzz")+tr(":已經關閉連接配接"));
    }
}
           

打開一個目錄

void MainWindow::processItem(QTreeWidgetItem* item,int)  //打開一個目錄
{
    QString name = item->text(0);
    if (isDirectory.value(name)) {  //如果這個檔案是個目錄,則打開
        ui->fileTreeWidget->clear();
        isDirectory.clear();
        currentPath += '/';
        currentPath += name;
        ftpClient->cd(name);
        ftpClient->list();
        //       ui->cdToParentButton->setEnabled(true);
    }
}
           

總結:

由于ftp是異步的,如果需要實時監測目前下載下傳檔案,需要使用多線程。

繼續閱讀