QT开发之FTP

上篇文章讲到了HTTP协议,这篇文章我们使用FTP协议来登录我的个人网站,在稳重贴出的代码中,这个服务器是随便填的,测试是登录成功的,有一个BUG,就是必须点击两次连接按钮才能够登录成功,可以下载文件,但是没有实现上传文件,大家可以自行去实现,我写博客的目的是为了备忘,在脑海中有一个印象,当在我的实际项目中需要用到这一块知识的时候我在来深入研究,现在只需要有一个大致的印象,方便以后的开发.


有网友反映说我写的文章有点偏基础,这一点我也是承认的.因为我还是学生,现在的目的是补充自己的知识技能拓展自己的视野,等我到实际工作的时候才会朝着某一个方向深入研究,同时会给大家带来更加优质的文章.


新建Qt Gui应用,项目名称是myFTP,其他默认.在工程问价中添加QT       += network

mian.cpp

#include <QtGui/QApplication>
#include "mainwindow.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
    MainWindow w;
    w.show();
    
    return a.exec();
}

mianwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QFtp>
#include <QTextCodec>
#include <QHash>

class QFtp;
class QFile;
class QUrlInfo;
class QTreeWidgetItem;

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT
    
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    
private:
    Ui::MainWindow *ui;
    QFtp *ftp;
    QHash<QString, bool> isDirectory;
    QString currentPath;
    QFile *file;

private slots:
    void ftpCommandStarted(int);
    void ftpCommandFinished(int, bool);

    void updateDataTransferProgress(qint64, qint64 );

    void addToList(const QUrlInfo &urlInfo);

    void processItem(QTreeWidgetItem*, int);

    void on_connectButton_clicked();
    void on_cdToParentButton_clicked();
    void on_downloadButton_clicked();

};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFile>
#include <QTreeWidgetItem>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->progressBar->setValue(0);
    connect(ui->fileList, SIGNAL(itemActivated(QTreeWidgetItem*, int)),
            this, SLOT(processItem(QTreeWidgetItem*, int)));
}

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

void MainWindow::ftpCommandStarted(int)
{
    int id = ftp->currentCommand();
    switch (id)
    {
    case QFtp::ConnectToHost :
        ui->label->setText(tr("正在连接服务器..."));
        break;
    case QFtp::Login :
        ui->label->setText(tr("正在登录..."));
        break;
    case QFtp::Get :
        ui->label->setText(tr("正在下载文件..."));
        break;
    case QFtp::Close :
        ui->label->setText(tr("正在关闭连接..."));
    }
}

void MainWindow::ftpCommandFinished(int id, bool error)
{
    //if(ftp->currentCommand() == QFtp::ConnectToHost)
    if(id == QFtp::ConnectToHost)
    {
        if (error)
            ui->label->setText(tr("连接服务器出现错误:%1").arg(ftp->errorString()));
        else
            ui->label->setText(tr("连接服务器成功"));
    }
    else  if(id == QFtp::Login)
    {
        if(error)
            ui->label->setText(tr("登录出现错误:%1").arg(ftp->errorString()));
        else
        {
            ui->label->setText(tr("登录成功"));
            ftp->list();
        }
    }
    else  if(id == QFtp::Get)
    {
        if(error)
            ui->label->setText(tr("下载出现错误:%1").arg(ftp->errorString()));
        else {
            ui->label->setText(tr("下载成功"));
            file->close();
        }
        ui->downloadButton->setEnabled(true);
    }
    else if(id == QFtp::List)
    {
        if(isDirectory.isEmpty())
        {
            ui->fileList->addTopLevelItem(new QTreeWidgetItem(QStringList()<< tr("<empty>")));
            ui->fileList->setEnabled(false);
            ui->label->setText(tr("该目录为空"));
        }
    }
    else  if(id == QFtp::Close)
    {
        ui->label->setText(tr("已经关闭连接"));
    }
}

void MainWindow::on_connectButton_clicked()
{
    ui->fileList->clear();
    currentPath.clear();
    isDirectory.clear();
    ftp = new QFtp(this);
    connect(ftp, SIGNAL(commandStarted(int)), this, SLOT(ftpCommandStarted(int)));
    connect(ftp, SIGNAL(commandFinished(int, bool)),
            this, SLOT(ftpCommandFinished(int, bool)));
    connect(ftp, SIGNAL(listInfo(QUrlInfo)), this, SLOT(addToList(QUrlInfo)));
    connect(ftp, SIGNAL(dataTransferProgress(qint64, qint64)),
            this, SLOT(updateDataTransferProgress(qint64, qint64)));
    QString ftpServer = ui->ftpServerLineEdit->text();
    QString userName = ui->userNameLineEdit->text();
    QString passWord = ui->passWordLineEdit->text();

    qDebug() << "ftpServer" << ftpServer;
    qDebug() << "userName" << userName;
    qDebug() << "passWord" << passWord;
    ftp->connectToHost(ftpServer, 324);
    ftp->login(userName, passWord);
}

void MainWindow::addToList(const QUrlInfo &urlInfo)
{
    QTreeWidgetItem *item = new QTreeWidgetItem;
    item->setText(0, urlInfo.name());
    item->setText(1, QString::number(urlInfo.size()));
    item->setText(2, urlInfo.owner());
    item->setText(3, urlInfo.group());
    item->setText(4, urlInfo.lastModified().toString("MMM dd yyyy"));
    QPixmap pixmap(urlInfo.isDir() ? "../myFTP/dir.png" : "../myFTP/file.png");
    item->setIcon(0, pixmap);
    isDirectory[urlInfo.name()] = urlInfo.isDir();
    ui->fileList->addTopLevelItem(item);
    if (!ui->fileList->currentItem()) {
        ui->fileList->setCurrentItem(ui->fileList->topLevelItem(0));
        ui->fileList->setEnabled(true);
    }
}

void MainWindow::processItem(QTreeWidgetItem *item, int)
{
    QString name = item->text(0);

    if (isDirectory.value(name)) {
        ui->fileList->clear();
        isDirectory.clear();
        currentPath += "/";
        currentPath += name;
        ftp->cd(name);
        ftp->list();
        ui->cdToParentButton->setEnabled(true);
    }
}


void MainWindow::on_cdToParentButton_clicked()
{
    ui->fileList->clear();
    isDirectory.clear();
    currentPath = currentPath.left(currentPath.lastIndexOf('/'));
    if (currentPath.isEmpty()) {
        ui->cdToParentButton->setEnabled(false);
        ftp->cd("/");
    } else {
        ftp->cd(currentPath);
    }
    ftp->list();
}


void MainWindow::on_downloadButton_clicked()
{
    QString fileName = ui->fileList->currentItem()->text(0);
    file = new QFile(fileName);
    if (!file->open(QIODevice::WriteOnly)) {
        delete file;
        return;
    }
    ui->downloadButton->setEnabled(false);
    ftp->get(ui->fileList->currentItem()->text(0), file);
}

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

mainwndow.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>510</width>
    <height>363</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralWidget">
   <widget class="QLabel" name="label">
    <property name="geometry">
     <rect>
      <x>10</x>
      <y>290</y>
      <width>371</width>
      <height>16</height>
     </rect>
    </property>
    <property name="text">
     <string>FTP客户端</string>
    </property>
   </widget>
   <widget class="QLabel" name="label_2">
    <property name="geometry">
     <rect>
      <x>10</x>
      <y>20</y>
      <width>61</width>
      <height>16</height>
     </rect>
    </property>
    <property name="text">
     <string>FTP服务器:</string>
    </property>
   </widget>
   <widget class="QLineEdit" name="ftpServerLineEdit">
    <property name="geometry">
     <rect>
      <x>80</x>
      <y>20</y>
      <width>351</width>
      <height>20</height>
     </rect>
    </property>
    <property name="text">
     <string>ftp.6kshknb4wjwvht0qLinux.com</string>
    </property>
   </widget>
   <widget class="QLabel" name="label_3">
    <property name="geometry">
     <rect>
      <x>10</x>
      <y>50</y>
      <width>54</width>
      <height>12</height>
     </rect>
    </property>
    <property name="text">
     <string>用户名:</string>
    </property>
   </widget>
   <widget class="QLineEdit" name="userNameLineEdit">
    <property name="geometry">
     <rect>
      <x>80</x>
      <y>50</y>
      <width>141</width>
      <height>20</height>
     </rect>
    </property>
    <property name="toolTip">
     <string>默认用户名请使用:anonymous ,此时密码任意。</string>
    </property>
    <property name="text">
     <string>know</string>
    </property>
   </widget>
   <widget class="QLabel" name="label_4">
    <property name="geometry">
     <rect>
      <x>250</x>
      <y>50</y>
      <width>54</width>
      <height>12</height>
     </rect>
    </property>
    <property name="text">
     <string>密码:</string>
    </property>
   </widget>
   <widget class="QLineEdit" name="passWordLineEdit">
    <property name="geometry">
     <rect>
      <x>310</x>
      <y>50</y>
      <width>121</width>
      <height>20</height>
     </rect>
    </property>
    <property name="text">
     <string>sadasdasdasd</string>
    </property>
    <property name="echoMode">
     <enum>QLineEdit::Password</enum>
    </property>
   </widget>
   <widget class="QPushButton" name="connectButton">
    <property name="geometry">
     <rect>
      <x>450</x>
      <y>50</y>
      <width>51</width>
      <height>23</height>
     </rect>
    </property>
    <property name="text">
     <string>连接</string>
    </property>
   </widget>
   <widget class="QTreeWidget" name="fileList">
    <property name="geometry">
     <rect>
      <x>10</x>
      <y>80</y>
      <width>491</width>
      <height>161</height>
     </rect>
    </property>
    <column>
     <property name="text">
      <string>文件</string>
     </property>
    </column>
    <column>
     <property name="text">
      <string>大小</string>
     </property>
    </column>
    <column>
     <property name="text">
      <string>拥有者</string>
     </property>
    </column>
    <column>
     <property name="text">
      <string>所属组</string>
     </property>
    </column>
    <column>
     <property name="text">
      <string>修改日期</string>
     </property>
    </column>
   </widget>
   <widget class="QProgressBar" name="progressBar">
    <property name="geometry">
     <rect>
      <x>10</x>
      <y>250</y>
      <width>391</width>
      <height>23</height>
     </rect>
    </property>
    <property name="value">
     <number>24</number>
    </property>
   </widget>
   <widget class="QPushButton" name="cdToParentButton">
    <property name="geometry">
     <rect>
      <x>414</x>
      <y>250</y>
      <width>81</width>
      <height>23</height>
     </rect>
    </property>
    <property name="text">
     <string>返回上级目录</string>
    </property>
   </widget>
   <widget class="QPushButton" name="downloadButton">
    <property name="geometry">
     <rect>
      <x>414</x>
      <y>290</y>
      <width>81</width>
      <height>23</height>
     </rect>
    </property>
    <property name="text">
     <string>下载</string>
    </property>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menuBar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>510</width>
     <height>22</height>
    </rect>
   </property>
  </widget>
  <widget class="QToolBar" name="mainToolBar">
   <attribute name="toolBarArea">
    <enum>TopToolBarArea</enum>
   </attribute>
   <attribute name="toolBarBreak">
    <bool>false</bool>
   </attribute>
  </widget>
  <widget class="QStatusBar" name="statusBar"/>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>

程序运行效果如下:


       

                                                                                                                                     文章出自:Linux_Google


已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页