windows下vs2017和Qt5.9.7环境下使用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


配置

在pro文件中完成此两项配置

文件的拷贝

目录下生成的*.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
}

例如,如果要连接并登录到 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是异步的,如果需要实时监测当前下载文件,需要使用多线程。

发布了16 篇原创文章 · 获赞 22 · 访问量 1004

猜你喜欢

转载自blog.csdn.net/weixin_41882459/article/details/103127235