基本信息
源码名称:FTP客户端实例源码(基于QT)
源码大小:15.61M
文件格式:.rar
开发语言:C/C++
更新时间:2019-04-21
   友情提示:(无需注册或充值,赞助后即可获取资源下载链接)

     嘿,亲!知识可是无价之宝呢,但咱这精心整理的资料也耗费了不少心血呀。小小地破费一下,绝对物超所值哦!如有下载和支付问题,请联系我们QQ(微信同号):813200300

本次赞助数额为: 2 元 
   源码介绍

实现的ftp客户端,能列出/更改目录,上下传文件,显示文件列表等选项。 

基于QT的FTP客户端

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QTextCodec>
#include <QMouseEvent>
#include <QPoint>
#include <QButtonGroup>
#include <QMenu>
#include <QHeaderView>
#include "qftp.h"
#include <QInputDialog>
#include <QMessageBox>
#include <QDebug>
#include <QFileDialog>
#include <QHeaderView>
#include <QAction>
#include <QPalette>


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
     initform();
    setContextMenuPolicy(Qt::DefaultContextMenu);//
}

MainWindow::~MainWindow()
{
    delete ui;
}
//初始化窗口
void MainWindow::initform()
{
    ftp  = new QFtp();
    ui->progressBar->setValue(0);
    ui->lineEdit->setText("192.168.0.108");
    ui->lineEdit_2->setText("Angelzhx");
    ui->lineEdit_3->setText("123456");
    ui->lineEdit_4->setText("D:/");
     ftp->setTransferMode(QFtp::Active);
     // ftp->setTransferMode(QFtp::Passive); beidong
   connect(ftp,SIGNAL(commandStarted(int)),this,SLOT(ftpCommandStarted(int)));
   connect(ui->treeWidget,SIGNAL(itemActivated(QTreeWidgetItem*,int)),
           this,SLOT(processItem(QTreeWidgetItem*,int)));
   this->setFixedSize(this->size());
    connect(ftp,SIGNAL(dataTransferProgress(qint64,qint64)),this,SLOT(updateDataTransferProgress(qint64,qint64)));
    connect(ftp,SIGNAL(listInfo(QUrlInfo)),this,SLOT(addToList(QUrlInfo)));

    connect(ftp,SIGNAL(commandFinished(int,bool)),this,SLOT(ftpCommandFinished(int,bool)));
   connect(ftp,SIGNAL(stateChanged(int)),this,SLOT(ftpStateChanged(int)));

}

//登陆服务器
void MainWindow::on_pushButton_clicked()
{

    if(ui->pushButton->text() == "注销")
    {
        ftp->close();
        ui->pushButton->setText(tr("connect"));
        ui->treeWidget->clear();
        currentPath.clear();
        isDirectory.clear();
    }
    else if(ui->pushButton->text() == "connect")
    {
        ui->treeWidget->clear();
        currentPath.clear();
        isDirectory.clear();
        QString ip=ui->lineEdit->text();
        QString username=ui->lineEdit_2->text();
        QString pwd=ui->lineEdit_3->text();
        ftp->connectToHost(ip, 21);
        ftp->login(username, pwd);
    }

}
//解决中文乱码问题
QString MainWindow::toSpecialEncoding(const QString &inputStr)
{
    QTextCodec *codec= QTextCodec::codecForName("gbk");
    if (codec)
    {
        return QString::fromLatin1(codec->fromUnicode(inputStr));
    }
    else
    {
        return QString("");
    }
}
//文件列表信息输入到表格
void MainWindow::addToList(const QUrlInfo &urlInfo)
{
    QString fileSize; //用于存储文件大小,根据文件大小字节,设置文件在树列表的单位
    if(urlInfo.size() >=0 && urlInfo.size() < 1024)
    {
        fileSize = QString::number(urlInfo.size())   "Byte";
    }
    else if(urlInfo.size() >= 1024 && urlInfo.size() < 1024*1024)
    {
        fileSize = QString::number(urlInfo.size()/1024.0,'f',2)   "KB";
    }
    else if(urlInfo.size() >= 1024*1024 && urlInfo.size() < 1024*1024*1024)
    {
        fileSize = QString::number(urlInfo.size()/1024/1024.0,'f',2)   "MB";
    }
    else if(urlInfo.size() >= 1024*1024*1024)
    {
        fileSize = QString::number(urlInfo.size()/1024/1024/1024.0,'f',2)   "GB";
    }
    //添加文件各信息到树列表
    QTreeWidgetItem *item = new QTreeWidgetItem;
    //转换UrlInfo中的文件名编码,解决乱码
    item->setText(0, urlInfo.name());
    item->setText(1, fileSize);
    item->setText(2, urlInfo.lastModified().toString("yyyy/MM/dd hh:mm"));
  //  item->setText(3, urlInfo.owner());
   // item->setText(4, urlInfo.group());
    //显示文件和文件夹图标
    QPixmap pixmap(urlInfo.isDir() ? ":/1111/dir.png" : ":/1111/file.png");
    item->setIcon(0, pixmap);
    //存储该路径是否为目录的信息
    isDirectory[urlInfo.name()] = urlInfo.isDir();
    ui->treeWidget->addTopLevelItem(item);
    if (!ui->treeWidget->currentItem())
    {
        ui->treeWidget->setCurrentItem(ui->treeWidget->topLevelItem(0));
        ui->treeWidget->setEnabled(true);
    }
}
//上传文件
void MainWindow::on_pushButton_2_clicked()
{
    QString filePath = QFileDialog::getOpenFileName(this,
                                                    tr("打开文件"),
                                                    "./",
                                                    tr("All Files (*);"));
    if(filePath.isEmpty())
        return;
    //打开文件
  QFile   *file = new QFile(filePath);//
    if(!file->open(QIODevice::ReadWrite))
    {
        delete file;
        file = NULL;
        ui->textEdit->append(tr("本地文件:%1打开失败!").arg(file->fileName()));
        return;
    }

    QFileInfo fileinfo(filePath);
    fileName = fileinfo.fileName();
    QMessageBox::information(this,"information","Are you sure download :" fileName);
    //转换上传的文件名编码,解决上传带有中文文件名的文件出错的问题,开始上传
    ftp->put(file,toSpecialEncoding( fileName));
      ui->textEdit->append(tr("正在上传:%1......").arg(fileName));

}
/***************下载文件*****************/
void MainWindow::on_pushButton_3_clicked()
{

        //判断当前储存路径是否为空
        if(ui->lineEdit_4->text().isEmpty())
      {
           openSaveFilePath();
           return;
        }
        QString name = ui->treeWidget->currentItem()->text(0);
        QString str = toSpecialEncoding(name);
        if (isDirectory.value(str)) //如果选中的是目录,则返回
        {
            return;
        }
        else
        {

            downloadFile(name);

        }


}
void MainWindow::downloadFile(const QString &fileName)
{
    //获取当前树列表中选中的文件名,并加上保存路径
    serverFileName = fileName;
    savePath=ui->lineEdit_4->text();
     QString filepath;
    if(serverFileName==NULL)
    filepath = savePath;
    else
         filepath = savePath   "/"   serverFileName;
    file = new QFile(filepath);
     QMessageBox::information(this,"information","Are you sure download :" fileName);
    if (!file->open(QIODevice::WriteOnly))
    {
        delete file;
        ui->textEdit->append(tr("本地文件:%1创建失败!").arg(serverFileName));
        return;
    }

          ftp->get(fileName, file);


 ui->textEdit->append(tr("正在下载:%1......").arg(file->fileName()));
}

//打开文件
void MainWindow::on_pushButton_5_clicked()
{
    openSaveFilePath();
}
//选择文件存储路径
bool MainWindow::openSaveFilePath()
{
    savePath = QFileDialog::getExistingDirectory(this,tr("选择文件保存路径"),"./");
    if(savePath.isEmpty())
    {
        return false;
    }
    else
    {
       ui->lineEdit_4->setText(savePath);
       return true;
    }
}
void MainWindow::ftpCommandStarted(int)
{
    if(ftp->currentCommand() == QFtp::ConnectToHost){
        ui->label_6->setText(tr("正在连接到服务器…"));
    }
    if (ftp->currentCommand() == QFtp::Login){
        ui->label_6->setText(tr("正在登录…"));
    }
    if (ftp->currentCommand() == QFtp::Get){
       ui->label_6->setText(tr("正在下载…"));
    }
    if (ftp->currentCommand() == QFtp::Put){
        ui->label_6->setText(tr("正在上传…"));
    }
    else if (ftp->currentCommand() == QFtp::Close){
        ui->label->setText(tr("正在关闭连接…"));
    }
}
void MainWindow::ftpStateChanged(int state)
{
    if(state == QFtp::Unconnected)
    {
        ui->textEdit->append(tr("未连接到主机"));
    }
    if(state == QFtp::Connected)
    {
        ui->textEdit->append(tr("已经连接到主机"));
    }
    if(state == QFtp::HostLookup)
    {
        ui->textEdit->append(tr("正在查找主机"));
    }
    if(state == QFtp::LoggedIn)
    {
        ui->textEdit->append(tr("已经登录"));
    }
    if(state == QFtp::Closing)
    {
        ui->textEdit->append("连接正在关闭");
    }
}


void MainWindow::contextMenuEvent(QContextMenuEvent *event )
{

    popMenu = new QMenu(this);           //定义一个右键弹出菜单

    QAction *refresh=new QAction("刷新",this);
    popMenu->addAction(refresh);
    connect(refresh,SIGNAL(triggered(bool)),this,SLOT(refreshed()));
    QAction *reName=new QAction("重命名",this);
    popMenu->addAction(reName);
    connect(reName,SIGNAL(triggered(bool)),this,SLOT(fileRename()));
    QAction *removeFile=new QAction("删除",this);
    popMenu->addAction(removeFile);
    connect(removeFile,SIGNAL(triggered(bool)),this,SLOT(deleteFile()));
    QAction *createFolder=new QAction("新建文件夹",this);
    popMenu->addAction(createFolder);
    connect(createFolder,SIGNAL(triggered(bool)),this,SLOT(createNewFolder()));
    QAction *cancel=new QAction("concel",this);
    popMenu->addAction(cancel);
    connect(cancel,SIGNAL(triggered(bool)),this,SLOT(on_cancelBtn_clicked()));

   popMenu->move(cursor().pos());
   popMenu->show();

    //设置菜单风格

  popMenu->setStyleSheet("QMenu{background-color: white;}"
                           "QMenu::item {background-color: transparent;"
                           "padding:6px 30px;}"
                           "QMenu::item:selected {background-color: #2dabf9;}");


}
//刷新列表
void MainWindow::refreshed()
{
    ui->treeWidget->clear();
    ftp->list();
}
//重命名
void MainWindow::fileRename()
{
    QString oldName = ui->treeWidget->currentItem()->text(0);
    QString str = toSpecialEncoding(oldName);
    if(isDirectory.value(str))//选中的是文件夹,则返回
    {
        QMessageBox::information(this,tr("保存"),tr("<font size='6' color='#008ed5'>文件夹不能重命名!</font>"),QMessageBox::Ok);
        return;
    }
    bool ok;
    QString newName  = QInputDialog::getText(this, tr("重命名"),
                                         tr("新文件名:"),
                                         QLineEdit::Normal,tr(""),
                                         &ok,Qt::WindowCloseButtonHint);
    if(newName.isEmpty())
        return;
    ftp->rename(toSpecialEncoding(oldName),toSpecialEncoding(newName));
    refreshed();
}
//删除文件
void MainWindow::deleteFile()
{
    QString deleteFile = ui->treeWidget->currentItem()->text(0);
    QString str = toSpecialEncoding(deleteFile);
    if(isDirectory.value(str))
    {
        deleteFolder();
    }
    QTreeWidgetItem* item = ui->treeWidget->currentItem();
  /*  if(item->childCount() > 0)//如果有子节点,则删除
    {
        for(int i = 0; i < item->childCount(); i   )
        {
            deleleNode(item->child(i));
        }
    }*/
    delete item;
  /*  if(ui->treeWidget->topLevelItemCount()<= 0)
    {
        ui->cdToParentButton->setEnabled(true);
    }*/
    ftp->remove(toSpecialEncoding(deleteFile));

}
//进入目录
void MainWindow::processItem(QTreeWidgetItem *item, int column)
{
    Q_UNUSED(column)//解决未使用的变量出现警告的问题
    QString name = item->text(0);
    //转换树列表中的文件名编码,解决点击项目文件夹无反应的问题
    QString str  = toSpecialEncoding(name);
    if (isDirectory.value(str))
    {
        //如果这个文件是个目录,则打开
        ui->treeWidget->clear();
        isDirectory.clear();
        currentPath  = '/';
        currentPath  = str;
        ftp->cd(str);
        ftp->list();
      //  ui->cdToParentButton->setEnabled(true);
    }
}
//返回上一级菜单
void MainWindow::on_cdToParentButton_clicked()
{
    ui->treeWidget->clear();
    isDirectory.clear();
    currentPath = currentPath.left(currentPath.lastIndexOf('/'));
    if (currentPath.isEmpty())
    {
        ftp->cd("/");
    }
    else
    {
        ftp->cd(currentPath);
    }
    ftp->list();
}
void MainWindow::on_pushButton_4_clicked()
{
    on_cdToParentButton_clicked();

}
//创建文件夹
void MainWindow::createNewFolder()
{
    bool ok;
    QString folderName  = QInputDialog::getText(this, tr("新建文件夹"),
                                         tr("新文件夹名:"),
                                         QLineEdit::Normal,tr(""),
                                         &ok,Qt::WindowCloseButtonHint);
    if(folderName.isEmpty())
        return;
    ftp->mkdir(toSpecialEncoding(folderName));
    ui->treeWidget->clear();
    ftp->list();
}
void MainWindow::on_setButton_clicked()
{
    QMessageBox::about(this,tr("关于"),tr("FTP客户端\n\n"
                                 "--------------声明-----------------\n\n"
                                 "1.本软件仅供学习交流使用\n"
                                 "2.软件名称:FTP客户端\n"
                                 "3.软件版本:1.0\n"
                                 "4.软件作者:OnlyU\n"
                                 "5.邮箱:731482764@qq.com\n\n"

                                 "-------------软件优点--------------\n\n"
                                 "1.实现上传、下载、删除、新建文件夹、重命名、刷新\n"
                                 "2.实现访问服务器的可视化\n"
                                 "3.界面简洁(所有图片资源均为本人用PS软件制作)\n"
                                 "4.实现解决中文乱码问题\n"
                                 "5.实现右键菜单功能\n"

                                 "-------------软件不足--------------\n\n"
                                 "1.由于未经多次测试,可能存在BUG,望使用者与我联系\n"
                                 "2.批量上传下载暂未实现,断点续传也未实现\n"
                                 "3.上传特大会出现卡顿,原因未知\n"
                                 "4.由于时间精力有限,上述不足之处望谅解,待日后有时间予以解决\n\n"));
}
void MainWindow::updateDataTransferProgress(qint64 readBytes, qint64 totalBytes)
{
    ui->progressBar->setMaximum(totalBytes/1024);     //设置进度条的最大值 除1024目的是防止上传下载大文件时进度条卡顿
    ui->progressBar->setValue(readBytes/1024);         //设置进度条的当前值
}
//根据相应命令的完成,进行相应操作
void MainWindow::ftpCommandFinished(int, bool error)
{
    if(ftp->currentCommand() == QFtp::ConnectToHost)
    {
        if(error)
        {
            ui->textEdit->append(tr("连接服务器出现错误:%1").arg(ftp->errorString()));
        }
        else
           ui->label_6->setText(tr("连接到服务器成功"));
    }
    else if(ftp->currentCommand() == QFtp::Login)
    {
        if(error)
        {
            ui->textEdit->append(tr("登录出现错误:%1").arg(ftp->errorString()));
        }
        else
        {
            ui->pushButton->setText(tr("注销"));
            ui->label_6->setText("connect successful");
            ftp->list(); //发射listInfo()信号,显示文件列表
        }
    }
    else if(ftp->currentCommand() == QFtp::Get)
    {
        if(error)
        {
          ui->textEdit->append(tr("下载:%1被取消").arg(serverFileName));
            file->close();
            file->remove();
        }
        else
        {
            //在下载命令完成时,使下载按钮为可用,并关闭打开的文件。
       ui->label_6->setText(tr("已经完成下载"));
        ui->textEdit->append(tr("文件:%1下载完成").arg(serverFileName));
            file->close();
        }
        delete file;
    }
    else if(ftp->currentCommand() == QFtp::Put)
    {
        if(error)
        {
        // ui->textEdit->append(tr("上传:%1被取消").arg(fileName));
            file->close();
        }
        else
        {
            //然后,在上传命令完成时,使上传按钮可用,并关闭打开的文件。
         ui->label_6->setText(tr("已经完成上传"));
       ui->textEdit->append(tr("文件:%1上传完成").arg(fileName));
            refreshed();
          //  file->close();
        }
       // delete file;
    }
    //处理list命令完成时的情况:
    else if(ftp->currentCommand() == QFtp::List)
    {
        if(isDirectory.isEmpty())
        {
            //如果目录为空,显示“empty”
            ui->treeWidget->addTopLevelItem(new QTreeWidgetItem(QStringList()<< tr("<empty>")));
            ui->treeWidget->setEnabled(false);
            ui->label_6->setText(tr("该目录为空"));
          //  ui->cdToParentButton->setEnabled(true);
        }
    }
    else if(ftp->currentCommand() == QFtp::Close)
    {
        ui->textEdit->append(tr("已经关闭连接"));
        ui->label_6->setText(tr("已经关闭连接"));
    }
    else if(ftp->currentCommand() == QFtp::Rename)
    {
        ui->textEdit->append(tr("文件重命名成功"));
        refreshed();
    }
    else if(ftp->currentCommand() == QFtp::Mkdir)
    {
        ui->textEdit->append(tr("新建文件夹成功"));
        refreshed();
    }
    else if(ftp->currentCommand() == QFtp::Remove)
    {
       ui->textEdit->append(tr("文件删除成功"));
        refreshed();
    }
    else if(ftp->currentCommand() == QFtp::Rmdir)
    {
        ui->textEdit->append(tr("文件夹删除成功"));
        refreshed();
    }
}


//删除文件夹
void MainWindow::deleteFolder()
{
    QString folder = ui->treeWidget->currentItem()->text(0);
    QString str = toSpecialEncoding(folder);
    if(isDirectory.value(str))
    {
        ftp->rmdir(toSpecialEncoding(folder));
    }
}
//取消上传和下载
void MainWindow::on_cancelBtn_clicked()
{
    ftp->abort();
    if(file->exists())
    {
        file->close();
    }
    ui->progressBar->setValue(0);

}