在Qt5环境下使用自编译的QFtp库,参考官方提供的实例,对部分内容进行更改,实现了Ftp下载文件的客户端。
详细代码如下:
.h头文件
#ifndef FTPWINDOW_H
#define FTPWINDOW_H
#include <QDialog>
#include <QHash>
#include <QNetworkConfigurationManager>
QT_BEGIN_NAMESPACE
class QDialogButtonBox;
class QFile;
class QFtp;
class QLabel;
class QLineEdit;
class QTreeWidget;
class QTreeWidgetItem;
class QProgressDialog;
class QPushButton;
class QUrlInfo;
class QNetworkSession;
QT_END_NAMESPACE
namespace Ui {
class FtpWindow;
}
class FtpWindow : public QDialog
{
Q_OBJECT
public:
explicit FtpWindow(QWidget *parent = 0);
~FtpWindow();
QSize sizeHint() const;
private:
QString calFileSize(long long size);
private slots:
void connectOrDisconnect();
void downloadFile();
void cancelDownload();
void connectToFtp();
void ftpCommandFinished(int commandId, bool error);
void addToList(const QUrlInfo &urlInfo);
void processItem(QTreeWidgetItem *item, int column);
void cdToParent();
void updateDataTransferProgress(qint64 readBytes,
qint64 totalBytes);
void enableDownloadButton();
void enableConnectButton();
private:
Ui::FtpWindow *ui;
private:
QLabel *ftpServerLabel;
QLineEdit *ftpServerLineEdit;
QLabel *ftpUserLabel;
QLineEdit *ftpUserLineEdit;
QLabel *ftpPasswordLabel;
QLineEdit *ftpPasswordLineEdit;
QLabel *statusLabel;
QTreeWidget *fileList;
QPushButton *cdToParentButton;
QPushButton *connectButton;
QPushButton *downloadButton;
QPushButton *quitButton;
QDialogButtonBox *buttonBox;
QProgressDialog *progressDialog;
//![1]
QHash<QString, bool> isDirectory;
QString currentPath;
QFtp *ftp;
QFile *file;
QNetworkSession *networkSession;
QNetworkConfigurationManager manager;
};
#endif // FTPWINDOW_H
.cpp 源文件
#include "ftpwindow.h"
#include "ui_ftpwindow.h"
#include <QtWidgets>
#include <QtNetwork>
#include "qftp.h"
QString _ToSpecialEncoding(const QString &InputStr)
{
#ifdef Q_OS_WIN
return QString::fromLatin1(InputStr.toLocal8Bit());
#else
QTextCodec *codec= QTextCodec::codecForName("gbk");
if (codec)
{
return QString::fromLatin1(codec->fromUnicode(InputStr));
}
else
{
return QString("");
}
#endif
}
FtpWindow::FtpWindow(QWidget *parent) :
QDialog(parent),ftp(0), networkSession(0),
ui(new Ui::FtpWindow)
{
ui->setupUi(this);
this->resize(800, 600);
ftpServerLabel = new QLabel(tr("Ftp &server:"));
ftpServerLineEdit = new QLineEdit("ftp://xxx.xxx.xxx.xxx");
ftpServerLabel->setBuddy(ftpServerLineEdit);
ftpUserLabel = new QLabel(QString::fromLocal8Bit("用户名:"));
ftpUserLineEdit = new QLineEdit("xxxxxx");
ftpUserLabel->setBuddy(ftpUserLineEdit);
ftpPasswordLabel = new QLabel(QString::fromLocal8Bit("密码:"));
ftpPasswordLineEdit = new QLineEdit("xxxxxx");
ftpPasswordLineEdit->setEchoMode(QLineEdit::EchoMode::Password);
ftpPasswordLabel->setBuddy(ftpPasswordLineEdit);
statusLabel = new QLabel(tr("Please enter the name of an FTP server."));
fileList = new QTreeWidget;
fileList->setEnabled(false);
fileList->setRootIsDecorated(false);
fileList->setHeaderLabels(QStringList() << tr("Name") << tr("Size") << tr("Time"));
fileList->header()->setStretchLastSection(false);
connectButton = new QPushButton(tr("Connect"));
connectButton->setDefault(true);
cdToParentButton = new QPushButton;
cdToParentButton->setIcon(QPixmap(":/images/cdtoparent.png"));
cdToParentButton->setEnabled(false);
downloadButton = new QPushButton(tr("Download"));
downloadButton->setEnabled(false);
quitButton = new QPushButton(tr("Quit"));
buttonBox = new QDialogButtonBox;
buttonBox->addButton(downloadButton, QDialogButtonBox::ActionRole);
buttonBox->addButton(quitButton, QDialogButtonBox::RejectRole);
progressDialog = new QProgressDialog(this);
progressDialog->accept();
connect(fileList, SIGNAL(itemActivated(QTreeWidgetItem*,int)),
this, SLOT(processItem(QTreeWidgetItem*,int)));
connect(fileList, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
this, SLOT(enableDownloadButton()));
connect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelDownload()));
connect(connectButton, SIGNAL(clicked()), this, SLOT(connectOrDisconnect()));
connect(cdToParentButton, SIGNAL(clicked()), this, SLOT(cdToParent()));
connect(downloadButton, SIGNAL(clicked()), this, SLOT(downloadFile()));
connect(quitButton, SIGNAL(clicked()), this, SLOT(close()));
QHBoxLayout *topLayout = new QHBoxLayout;
topLayout->addWidget(ftpServerLabel);
topLayout->addWidget(ftpServerLineEdit);
topLayout->addWidget(ftpUserLabel);
topLayout->addWidget(ftpUserLineEdit);
topLayout->addWidget(ftpPasswordLabel);
topLayout->addWidget(ftpPasswordLineEdit);
topLayout->addWidget(cdToParentButton);
topLayout->addWidget(connectButton);
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addLayout(topLayout);
mainLayout->addWidget(fileList);
mainLayout->addWidget(statusLabel);
mainLayout->addWidget(buttonBox);
setLayout(mainLayout);
setWindowTitle(tr("FTP"));
}
FtpWindow::~FtpWindow()
{
delete ui;
}
QSize FtpWindow::sizeHint() const
{
return QSize(1200, 500);
}
void FtpWindow::connectOrDisconnect()
{
if (ftp) {
ftp->abort();
ftp->deleteLater();
ftp = 0;
fileList->setEnabled(false);
cdToParentButton->setEnabled(false);
downloadButton->setEnabled(false);
connectButton->setEnabled(true);
connectButton->setText(tr("Connect"));
#ifndef QT_NO_CURSOR
setCursor(Qt::ArrowCursor);
#endif
statusLabel->setText(tr("Please enter the name of an FTP server."));
return;
}
#ifndef QT_NO_CURSOR
setCursor(Qt::WaitCursor);
#endif
if (!networkSession || !networkSession->isOpen()) {
if (manager.capabilities() & QNetworkConfigurationManager::NetworkSessionRequired) {
if (!networkSession) {
// Get saved network configuration
QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
settings.beginGroup(QLatin1String("QtNetwork"));
const QString id = settings.value(QLatin1String("DefaultNetworkConfiguration")).toString();
settings.endGroup();
// If the saved network configuration is not currently discovered use the system default
QNetworkConfiguration config = manager.configurationFromIdentifier(id);
if ((config.state() & QNetworkConfiguration::Discovered) !=
QNetworkConfiguration::Discovered) {
config = manager.defaultConfiguration();
}
networkSession = new QNetworkSession(config, this);
connect(networkSession, SIGNAL(opened()), this, SLOT(connectToFtp()));
connect(networkSession, SIGNAL(error(QNetworkSession::SessionError)), this, SLOT(enableConnectButton()));
}
connectButton->setEnabled(false);
statusLabel->setText(tr("Opening network session."));
networkSession->open();
return;
}
}
connectToFtp();
}
void FtpWindow::downloadFile()
{
QString fileName = fileList->currentItem()->text(0);
if (QFile::exists(fileName)) {
QMessageBox::information(this, tr("FTP"),
tr("There already exists a file called %1 in "
"the current directory.")
.arg(fileName));
return;
}
file = new QFile(fileName);
if (!file->open(QIODevice::WriteOnly)) {
QMessageBox::information(this, tr("FTP"),
tr("Unable to save the file %1: %2.")
.arg(fileName).arg(file->errorString()));
delete file;
return;
}
ftp->get(fileList->currentItem()->text(0), file);
progressDialog->setLabelText(tr("Downloading %1...").arg(fileName));
downloadButton->setEnabled(false);
progressDialog->exec();
}
void FtpWindow::cancelDownload()
{
ftp->abort();
if (file->exists()) {
file->close();
file->remove();
}
delete file;
}
void FtpWindow::connectToFtp()
{
ftp = new QFtp(this);
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)));
ftp->setTransferMode(QFtp::Active);
fileList->clear();
currentPath.clear();
isDirectory.clear();
QUrl url(ftpServerLineEdit->text());
if (!url.isValid() || url.scheme().toLower() != QLatin1String("ftp")) {
ftp->connectToHost(ftpServerLineEdit->text(), 21);
int logStatus = ftp->login(ftpUserLineEdit->text(),ftpPasswordLineEdit->text());
qDebug()<<logStatus;
} else {
ftp->connectToHost(url.host(), url.port(21));
if (!url.userName().isEmpty())
qDebug()<<ftp->login(QUrl::fromPercentEncoding(url.userName().toLatin1()), url.password());
else
qDebug()<<ftp->login(ftpUserLineEdit->text(),ftpPasswordLineEdit->text());
if (!url.path().isEmpty())
ftp->cd(url.path());
qDebug()<<url.path();
}
fileList->setEnabled(true);
connectButton->setEnabled(false);
connectButton->setText(tr("Disconnect"));
statusLabel->setText(tr("Connecting to FTP server %1...")
.arg(ftpServerLineEdit->text()));
}
void FtpWindow::ftpCommandFinished(int commandId, bool error)
{
#ifndef QT_NO_CURSOR
setCursor(Qt::ArrowCursor);
#endif
if (ftp->currentCommand() == QFtp::ConnectToHost) {
if (error) {
QMessageBox::information(this, tr("FTP"),
tr("Unable to connect to the FTP server "
"at %1. Please check that the host "
"name is correct.")
.arg(ftpServerLineEdit->text()));
connectOrDisconnect();
return;
}
statusLabel->setText(tr("Logged onto %1.")
.arg(ftpServerLineEdit->text()));
fileList->setFocus();
downloadButton->setDefault(true);
connectButton->setEnabled(true);
return;
}
if (ftp->currentCommand() == QFtp::Login)
ftp->list();
if (ftp->currentCommand() == QFtp::Get) {
if (error) {
statusLabel->setText(tr("Canceled download of %1.")
.arg(file->fileName()));
file->close();
file->remove();
} else {
statusLabel->setText(tr("Downloaded %1 to current directory.")
.arg(file->fileName()));
file->close();
}
delete file;
enableDownloadButton();
progressDialog->hide();
} else if (ftp->currentCommand() == QFtp::List) {
if (isDirectory.isEmpty()) {
fileList->addTopLevelItem(new QTreeWidgetItem(QStringList() << tr("<empty>")));
fileList->setEnabled(false);
}
}
}
void FtpWindow::addToList(const QUrlInfo &urlInfo)
{
QTreeWidgetItem *item = new QTreeWidgetItem;
QByteArray name = urlInfo.name().toLatin1();
qDebug()<<name;
item->setText(0, QString::fromLocal8Bit(name));
//QString fileSize = urlInfo.isDir()? " ":(calFileSize(urlInfo.size()));
item->setText(1, urlInfo.isDir()? " ":(calFileSize(urlInfo.size())));
// item->setText(2, urlInfo.owner());
// item->setText(3, urlInfo.group());
item->setText(4, urlInfo.lastModified().toString("yyyy/MM/dd HH:mm"));
QPixmap pixmap(urlInfo.isDir() ? ":/images/dir.png" : ":/images/file.png");
item->setIcon(0, pixmap);
isDirectory[urlInfo.name()] = urlInfo.isDir();
fileList->addTopLevelItem(item);
if (!fileList->currentItem()) {
fileList->setCurrentItem(fileList->topLevelItem(0));
fileList->setEnabled(true);
}
}
QString FtpWindow::calFileSize(long long size)
{
double fileSize = 0.0;
if(size>1024*1024*1024)
{
fileSize = size*1.0/(1024*1024*1024); // GB
return QString::number(fileSize, 'f', 2)+" GB";
}
if(size>1024*1024)
{
fileSize = size*1.0/(1024*1024); //MB
return QString::number(fileSize, 'f', 2)+" MB";
}
if(size>1024)
{
fileSize = size*1.0/1024; //KB
return QString::number(fileSize, 'f', 2)+" KB";
}
return QString::number(size)+" B";
}
void FtpWindow::processItem(QTreeWidgetItem *item, int column)
{
//QString name = item->text(0);
QString name = QString::fromLatin1(item->text(0).toLocal8Bit());
if (isDirectory.value(name)) {
fileList->clear();
isDirectory.clear();
currentPath += '/';
currentPath += name;
ftp->cd(name);
ftp->list();
cdToParentButton->setEnabled(true);
#ifndef QT_NO_CURSOR
setCursor(Qt::WaitCursor);
#endif
return;
}
}
void FtpWindow::cdToParent()
{
#ifndef QT_NO_CURSOR
setCursor(Qt::WaitCursor);
#endif
fileList->clear();
isDirectory.clear();
currentPath = currentPath.left(currentPath.lastIndexOf('/'));
if (currentPath.isEmpty()) {
cdToParentButton->setEnabled(false);
ftp->cd("/");
} else {
ftp->cd(currentPath);
}
ftp->list();
}
void FtpWindow::updateDataTransferProgress(qint64 readBytes,
qint64 totalBytes)
{
progressDialog->setMaximum(totalBytes);
progressDialog->setValue(readBytes);
}
void FtpWindow::enableDownloadButton()
{
QTreeWidgetItem *current = fileList->currentItem();
if (current) {
QString currentFile = current->text(0);
downloadButton->setEnabled(!isDirectory.value(currentFile));
} else {
downloadButton->setEnabled(false);
}
}
void FtpWindow::enableConnectButton()
{
// Save the used configuration
QNetworkConfiguration config = networkSession->configuration();
QString id;
if (config.type() == QNetworkConfiguration::UserChoice)
id = networkSession->sessionProperty(QLatin1String("UserChoiceConfiguration")).toString();
else
id = config.identifier();
QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
settings.beginGroup(QLatin1String("QtNetwork"));
settings.setValue(QLatin1String("DefaultNetworkConfiguration"), id);
settings.endGroup();
connectButton->setEnabled(true);
statusLabel->setText(tr("Please enter the name of an FTP server."));
}
ftp编译库下载地址:【免费】QFtp编译库VS2013-64、VS2015-64、MinGW32_QFtp库下载编译资源-CSDN文库
后续公众号会发布系列教程,更多内容请关注公众号:程序猿学习日记