QT学习(网络)
FTP
FTP的主要作用,就是让用户连接上一个远程计算机,查看远程计算机有哪些文件,然后把文件从远程计算机上拷贝到本地计算机,或者把本地计算机的文件送到远程计算机上。
注意:
我使用的是QT5.11.2,里面没有FTP的相关头文件,所以使用前记得根据以下链接配置!!!
链接: Qt5使用QFtp类库的操作过程.
进入代码:
***.pro
QT += core gui network
CONFIG(debug,debug|release){
LIBS += -lQt5Ftpd
}else{
LIBS += -lQt5Ftp
}
#这是我的qt地址
LIBS += -LD:/qt/QT/5.11.2/msvc2015_64/lib
界面:
***.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QFtp>
#include <QLabel>
#include <QtGui>
#include <QTreeWidgetItem>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_downloadButton_clicked();
void on_cdToParentButton_clicked();
void on_connectButton_clicked();
void ftpCommandStarted(int);
void ftpCommandFinished(int,bool);
void updateDataTransferProgress(qint64,qint64 );//更新进度条
//将服务器上的文件添加到Tree Widget中
void addToList(const QUrlInfo &urlInfo);
void processItem(QTreeWidgetItem*,int);//双击一个目录时显示其内容
private:
Ui::Widget *ui;
QHash<QString, bool> isDirectory; //用来存储一个路径是否为目录的信息
QString currentPath; //用来存储现在的路径
QFile *file;
QFtp *ftp;
};
#endif // WIDGET_H
***.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
ui->progressBar->setValue(0);
//鼠标双击列表中的目录时,我们进入该目录
connect(ui->fileList,SIGNAL(itemActivated(QTreeWidgetItem*,int)),
this,SLOT(processItem(QTreeWidgetItem*,int)));
}
Widget::~Widget()
{
delete ui;
}
/*****************************************************************************
我们在“连接”按钮的单击事件槽函数中新建了ftp对象,然后关联了相关的信号和槽。
这里的listInfo()信号由ftp->list()函数发射,它将在登录命令完成时调用,
下面我们提到。而dataTransferProgress()信号在数据传输时自动发射。
最后我们从界面上获得服务器地址,用户名和密码等信息,并以它们为参数执行连接和登录命令。
****************************************************************************/
void Widget::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();
ftp->connectToHost(ftpServer,21); //连接到服务器,默认端口号是21
ftp->login(userName,passWord); //登录
}
/******************************************************************************************
每当命令执行时,都会执行ftpCommandStarted()函数,它有一个参数int id,这个id就是调用命令时返回的id,
如int loginID= ftp->login();这时,我们就可以用if(id == loginID)来判断执行的是否是login()函数。
但是,我们不想为每个命令都设置一个变量来存储其返回值,所以,我们这里使用了ftp->currentCommand(),
它也能获取当前执行的命令的类型。在这个函数里我们让开始不同的命令时显示不同的状态信息。
********************************************************************************************/
void Widget::ftpCommandStarted(int)
{
if(ftp->currentCommand() == QFtp::ConnectToHost){
ui->label->setText(tr("正在连接到服务器..."));
}
if (ftp->currentCommand() == QFtp::Login){
ui->label->setText(tr("正在登录..."));
}
if (ftp->currentCommand() == QFtp::Get){
ui->label->setText(tr("正在下载..."));
}
else if (ftp->currentCommand() == QFtp::Close){
ui->label->setText(tr("正在关闭连接..."));
}
}
/********************************************************************
这个函数它是在一个命令执行结束时执行的。
它有两个参数,第一个intid,就是调用命令时返回的编号。
第二个是bool error,它标志现在执行的命令是否出现了错误。
如果出现了错误,那么error 为true ,否则为false。我们可以利用它来输出错误信息。
在这个函数中,我们在完成一条命令时显示不同的状态信息,并显示可能的出错信息。
在if (ftp->currentCommand() == QFtp::Get)中,
也就是已经完成下载时,我们让textBrowser显示下载的信息。
**********************************************************************/
void Widget::ftpCommandFinished(int,bool error)
{
ui->label->setText(tr("登录成功"));
ftp->list(); //发射listInfo()信号,显示文件列表
//然后,在下载命令完成时,我们使下载按钮可用,并关闭打开的文件。
ui->label->setText(tr("已经完成下载"));
ui->downloadButton->setEnabled(true);
file->close();
delete file;
if (ftp->currentCommand() == QFtp::List){
if (isDirectory.isEmpty())
{ //如果目录为空,显示“empty”
ui->fileList->addTopLevelItem(
new QTreeWidgetItem(QStringList()<< tr("<empty>")));
ui->fileList->setEnabled(false);
ui->label->setText(tr("该目录为空"));
}
}
}
/**********************************************************************************************
当ftp->list()函数执行时会发射listInfo()信号,此时就会执行addToList()函数,
在这里我们将文件信息显示在Tree Widget上,并在isDirectory中存储该文件的路径及其是否为目录的信息。
为了使文件与目录进行区分,我们使用了不同的图标file.png和dir.png来表示它们,这两个图标放在了工程文件夹中。
************************************************************************************************/
void Widget::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() ? ":/img/1.jpg" : ":/img/2.jpg");
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 Widget::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 Widget::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 Widget::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 Widget::updateDataTransferProgress( //进度条
qint64 readBytes,qint64 totalBytes)
{
ui->progressBar->setMaximum(totalBytes);
ui->progressBar->setValue(readBytes);
}
学习链接:
网络ftp