基于Qt的FTP编程

2 3 月, 2011 by edsionte Leave a reply »

在Qt中,与文件传输协议(FTP)相对应的类为QFtp。在这个类中,提供了许多与文件上传和下载有关的方法,这使得文件的上传与下载变得十分方便。本文所描述的FTP客户端的基本使用方法是:首先输入正确的FTP服务器地址,用户名以及密码;登录成功后将显示服务器中的文件列表;点击下载按钮对某个文件进行下载。用户界面可参考下图:

用户界面设计可见本文参考1和参考2,接下来将对具体的实现过程进行分析。

构造函数

在构造函数中,对用户界面进行了初始化,并隐藏了进度显示条。除此之外,还将itemActivated信号和processItem槽函数进行了连接。当用户双击(或单击,依据具体OS)TreeWidget中的某一条信息时,QTreeWidget类的对象fileList就会发送itemActivated信号。

01Widget::Widget(QWidget *parent) :
02    QWidget(parent),
03    ui(new Ui::Widget)
04{
05    ui->setupUi(this);
06    ui->progressBar->setValue(0);
07 
08    connect(ui->fileList, SIGNAL(itemActivated(QTreeWidgetItem*,int)),
09            this, SLOT(processItem(QTreeWidgetItem*,int)));
10}

on_connectButton_clicked()的实现

在连接按钮单击事件的槽函数中主要完成了两部分工作:登录FTP服务器以及几个信号和槽函数之间的连接,这几个信号均由FTP对象发出。当FTP命令开始执行时,便发出commandStarted信号;当FTP的命令执行完毕时,便发出commandFinished信号;当使用list命令列表显示目录的内容时候,listInfo信号将发出;最后在数据传输的过程中,会不断的发出dataTransferProgress信号以便更新进度显示条。

由于QFtp类中封装了许多与FTP有关成员函数,因此使用connectToHost成员函数可以登录到FTP服务器,使用login函数可以登录到服务器。

01void Widget::on_connectButton_clicked()
02{
03    ui->fileList->clear();
04    currentPath.clear();
05    isDirectory.clear();
06    ftp = new QFtp(this);
07 
08    connect(ftp, SIGNAL(commandFinished(int,bool)),
09            this, SLOT(ftpCommandFinished(int,bool)));
10    connect(ftp, SIGNAL(listInfo(QUrlInfo)), this, SLOT(addToList(QUrlInfo)));
11    connect(ftp, SIGNAL(dataTransferProgress(qint64,qint64)),
12            this, SLOT(updateDataTransferProgress(qint64,qint64)));
13 
14    QString ftpServer = ui->ftpServerLineEdit->text();
15    QString userName = ui->userNameLineEdit->text();
16    QString passWord = ui->passWordLineEdit->text();
17 
18    ftp->connectToHost(ftpServer, 21);//连接到服务器,默认端口是21;
19    ftp->login(userName, passWord);//登录;
20}

ftpCommandFinished()的实现

当FTP命令执行完毕后,将执行ftpCommandFinished函数。与本文所描述的命令有ConnectToHost()、Login()、Get()、Close()和List()。通过currentCommand成员函数可以具体得到当前执行完毕命令的id,因此根据不同命令的id在用户界面上显示不同的命令状态。

01void Widget::ftpCommandFinished(int, bool error)
02{
03    if (ftp->currentCommand() == QFtp::ConnectToHost) {
04        if (error)
05            ui->label->setText(tr("connecting error %1").arg(ftp->errorString()));
06        else
07            ui->label->setText(tr("connecting success!"));
08    }
09 
10    if (ftp->currentCommand() == QFtp::Login) {
11        if (error)
12            ui->label->setText(tr("login error").arg(ftp->errorString()));
13        else {
14            ui->label->setText(tr("login success!"));
15            ftp->list();
16        }
17    }
18    //部分代码省略
19}

on_downloadButton_clicked()的实现

当单击下载按钮后,将进入该函数进行相应文件的下载。首先通过fileList对象中的成员函数得到要下载文件的名称,在打开该文件,最后通过get函数获取数据。

01void Widget::on_downloadButton_clicked()
02{
03    QString fileName = ui->fileList->currentItem()->text(0);
04    file = new QFile(fileName);
05    if (!file->open(QIODevice::WriteOnly)) {
06        delete file;
07        return;
08    }
09 
10    ui->downloadButton->setEnabled(false);
11    ftp->get(ui->fileList->currentItem()->text(0), file);
12}

addToList()的实现

当对FTP服务器上某个目录执行list()命令时,对于list()找到的每一个文件都会发出listInfo()信号。该信号会使得addToList函数执行,以便在treeWidget上增加一条新的文件信息。

因此,该函数首先根据urlInfo参数建立一条新的文件信息,然后再利用addTopLevelItem成员函数将该条新的文件信息加入到treeWidget最顶端。

01void Widget::addToList(const QUrlInfo &urlInfo)
02{
03    QTreeWidgetItem *item = new QTreeWidgetItem;
04    item->setText(0, urlInfo.name());
05    item->setText(1, QString::number(urlInfo.size()));
06    item->setText(2, urlInfo.owner());
07    item->setText(4, urlInfo.lastModified().toString("mmm dd yyyy"));
08    QPixmap pixmap(urlInfo.isDir() ? "../dir.png" : "../file.png");
09    item->setIcon(0, pixmap);
10    isDirectory[urlInfo.name()] = urlInfo.isDir();
11 
12    //存储该路径是否为目录的信息;
13    ui->fileList->addTopLevelItem(item);
14    if (!ui->fileList->currentItem()) {
15        ui->fileList->setCurrentItem(ui->fileList->topLevelItem(0));
16        ui->fileList->setEnabled(true);
17    }
18}

processItem()的实现

当双击文件列表中某一项时候,如果该项所显示的文件为目录,则进入该目录中显示其内部的文件列表。上述的内容即为processItem函数所要完成的工作。

01void Widget::processItem(QTreeWidgetItem *item, int)
02{
03    //打开一个目录;
04    QString name = item->text(0);
05    if (isDirectory.value(name)) {
06        ui->fileList->clear();
07        isDirectory.clear();
08        currentPath += '/';
09        currentPath += name;
10        ftp->cd(name);
11        ftp->list();
12        ui->cdToParentButton->setEnabled(true);
13    }
14}

updateDataTransferProgress()的实现

每当FTP服务器端的数据返回时,就引发该函数的执行。该函数的主要工作即更新进度条的显示。

1void Widget::updateDataTransferProgress(qint64 readBytes, qint64 totalBytes)
2{
3    ui->progressBar->setMaximum(totalBytes);
4    ui->progressBar->setValue(readBytes);
5}

 

未完待续~
参考:

1. Qt Assistant

2. http://www.yafeilinux.com/?p=757

3. C++ GUI Qt 4编程(第二版); 电子工业出版社;Blanchette,J,Summerfield,M 著;闫锋欣 等译;

Advertisement

发表回复

windows 7 ultimate product key

windows 7 ultimate product key

winrar download free

winrar download free

winzip registration code

winzip registration code

winzip free download

winzip free download

winzip activation code

winzip activation code

windows 7 key generator

windows 7 key generator

winzip freeware

winzip freeware

winzip free download full version

winzip free download full version

free winrar download

free winrar download

free winrar

free winrar

windows 7 crack

windows 7 crack

windows xp product key

windows xp product key

windows 7 activation crack

windows7 activation crack

free winzip

free winzip

winrar free download

winrar free download

winrar free

winrar free

download winrar free

download winrar free

windows 7 product key

windows 7 product key