使用QFtp类,实现FTP客户端的登录、上传、下载、删除、创建文件夹、返回等基础功能

📅 2026/7/15 14:19:57
使用QFtp类,实现FTP客户端的登录、上传、下载、删除、创建文件夹、返回等基础功能
1、介绍FTP是基于TCP/IP的一种应用层文件传输协议通过建立FTP服务器默认端口21-客服端的形式在各个主机间传输文件。Qt5.0之后移除了QFtp类基于FTP协议实现的一个类使用 QNetworkAccessManager 可以实现 Ftp 的上传/下载功能后者在性能上和稳定性上有所提升。但有些原本 QFtp 有的功能 QNetworkAccessManager 却没有提供例如list、cd、remove、mkdir、rmdir、rename 等前者的功能更加完善提供的API更多更加便于开发者使用。最为新手练习或者开发FTP相关功能和一般的应用当然选择QFtp更加有利。使用QFtp只需要把编译好的类文件添加到项目中即可Qftp类文件下载地址百度网盘链接: https://pan.baidu.com/s/1nbuKK6Tv35RowRsXwpuWUw?pwd5suc2、准备1、需要已经配置好的FTP服务器2、工程文件中需要添加QT network设计图文件结构其中红框圈住的是新增的项目文件qftp和qurlinfo是添加进入项目的Qftp类文件。3、功能要点1、登陆模式设置成被动连接否则连接服务器和登录会异常m_ftp-setTransferMode(QFtp::TransferMode::Passive);2、treeWidget的右键菜单出现位置需要特殊处理不可以直接使用pospos位置并不是鼠标实际显示的位置。//校正鼠标点的位置保证菜单出现在鼠标点击的位置 QPoint localPnt ui-treeWidget-viewport()-mapToGlobal(pos); pMenu-exec(localPnt);3、ftp服务器上文件路径地址的问题。登陆成功默认进入ftp服务器文件夹的根目录根据用户操作来确定所进入的文件夹和目录地址所以可以添加变量来确定当前文件所在目录。4、完整代码MainWindow.h#ifndef MAINWINDOW_H #define MAINWINDOW_H #include QMainWindow #include QMessageBox #include QTreeWidget #include qftp.h namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent 0); ~MainWindow(); protected: void closeEvent(QCloseEvent *event) override; private: void InitSlot(); //登录ftp服务器 void Login(); //操作提示 void OperationInfo(const QString info,QMessageBox::Icon icon); //修改按钮状态 void ActionStatus(bool enable); private slots: //响应命令开始 void OnFtpCommandStart(int commandId); //响应命令结束 void OnFtpCommandFinished(int commandId,bool isError); //响应展示文件列表 void OnAddListInfo(const QUrlInfo urlInfo); //响应进度条 void OnUpdateProgress(qint64 readBytes,qint64 totalBytes); //响应返回上一级 void OnActionBackToParent(); //响应上传信号 void OnActionUpload(); //响应下载信号 void OnActionDowload(); //响应获取文件列表操作 void OnActionList(); //响应新建操作 void OnActionNewFile(); //响应删除操作 void OnActionRemove(); //响应treeWidget点击Item事件 void OnTreeWidgetItemActived(QTreeWidgetItem *item, int column); //响应treeWidget右键事件 void OnMenuRequest(const QPoint pos); private: Ui::MainWindow *ui; QFtp* m_ftp nullptr; QHashQString,bool m_hashDirectory; }; #endif // MAINWINDOW_HMainWindow.cpp#include AddNewFloderDialog.h #include MainWindow.h #include ui_MainWindow.h #include QMessageBox #include QDebug #include QFileDialog MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui-setupUi(this); InitSlot(); } MainWindow::~MainWindow() { delete ui; } void MainWindow::closeEvent(QCloseEvent *event) { if(m_ftp ! nullptr) { m_ftp-abort(); m_ftp-close(); delete m_ftp; } } void MainWindow::InitSlot() { m_ftp new QFtp(this); connect(m_ftp,QFtp::commandStarted,this,MainWindow::OnFtpCommandStart); connect(m_ftp,QFtp::commandFinished,this,MainWindow::OnFtpCommandFinished); connect(m_ftp,QFtp::listInfo,this,MainWindow::OnAddListInfo); connect(m_ftp,QFtp::dataTransferProgress,this,MainWindow::OnUpdateProgress); //菜单栏操作 connect(ui-Login,QAction::triggered,[](){ Login();}); connect(ui-Quit,QAction::triggered,this,MainWindow::close); connect(ui-List,QAction::triggered, this,MainWindow::OnActionList); connect(ui-Back,QAction::triggered,this,MainWindow::OnActionBackToParent); connect(ui-Upload,QAction::triggered,this,MainWindow::OnActionUpload); connect(ui-Download,QAction::triggered,this,MainWindow::OnActionDowload); connect(ui-Newfile,QAction::triggered,this,MainWindow::OnActionNewFile); connect(ui-Removefile,QAction::triggered,this,MainWindow::OnActionRemove); //文件列表操作 connect(ui-treeWidget,QTreeWidget::itemActivated,this,MainWindow::OnTreeWidgetItemActived); ActionStatus(false); //添加右键菜单 ui-treeWidget-setContextMenuPolicy(Qt::CustomContextMenu); connect(ui-treeWidget,QTreeWidget::customContextMenuRequested,this,MainWindow::OnMenuRequest); } void MainWindow::Login() { if(m_ftp-state() QFtp::State::Connected) return; m_ftp-setTransferMode(QFtp::TransferMode::Passive); m_ftp-connectToHost(10.168.1.100,21); m_ftp-login(ftp,ftp); } void MainWindow::OperationInfo(const QString info, QMessageBox::Icon icon) { QMessageBox* message new QMessageBox; message-setModal(false); message-setIcon(icon); message-setText(info); message-setAttribute(Qt::WA_DeleteOnClose); message-show(); } void MainWindow::ActionStatus(bool enable) { ui-List-setEnabled(enable); ui-Back-setEnabled(enable); ui-menuFile-setEnabled(enable); if(enable) { ui-List-triggered(); } } void MainWindow::OnFtpCommandStart(int commandId) { switch (commandId) { case QFtp::ConnectToHost: qDebug()开始连接服务器; break; case QFtp::Login: qDebug()开始进行登录; break; case QFtp::List: qDebug()开始获取文件列表; break; case QFtp::Cd: qDebug()开始进入文件夹; break; case QFtp::Close: qDebug()开始关闭连接; break; case QFtp::Get: qDebug()开始下载文件; break; case QFtp::Put: qDebug()开始上传文件; break; case QFtp::Mkdir: qDebug()开始创建文件夹; break; case QFtp::Rmdir: qDebug()开始删除文件夹; break; case QFtp::SetTransferMode: qDebug()开始设置连接模式; break; case QFtp::SetProxy: qDebug()开始设置代理; break; default: qDebug()开始其他操作commandId; break; } } void MainWindow::OnFtpCommandFinished(int commandId, bool isError) { switch (commandId) { case QFtp::ConnectToHost: if(isError) qDebug()连接服务器失败; else { ActionStatus(true); qDebug()连接服务器成功; } break; case QFtp::Login: if(isError) qDebug()登录失败; else { qDebug()登录成功; ActionStatus(true); } case QFtp::List: if(isError) qDebug()获取文件列表失败; else qDebug()获取文件列表成功; case QFtp::Cd: if(isError) qDebug()打开文件夹失败; else qDebug()打开文件夹成功; case QFtp::Close: if(isError) qDebug()关闭连接失败; else qDebug()关闭连接成功; case QFtp::Get: if(isError) qDebug()下载失败; else qDebug()下载成功; case QFtp::Put: if(isError) qDebug()上传失败; else qDebug()上传成功; case QFtp::Mkdir: if(isError) qDebug()创建文件夹失败; else qDebug()创建文件夹成功; case QFtp::Rmdir: if(isError) qDebug()删除文件夹失败; else qDebug()删除文件夹成功; case QFtp::SetTransferMode: if(isError) qDebug()设置连接模式失败; else qDebug()设置连接模式成功; case QFtp::SetProxy: if(isError) qDebug()设置代理失败; else qDebug()设置代理成功; default: if(isError) qDebug()操作失败commandId; else qDebug()操作成功commandId; break; } } void MainWindow::OnAddListInfo(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(yyyy-MM-dd HH:mm:ss)); QPixmap pixmap(urlInfo.isDir() ? :/images/folder.png : :/images/file.png); item-setIcon(0,pixmap); ui-treeWidget-addTopLevelItem(item); m_hashDirectory[urlInfo.name()] urlInfo.isDir(); } void MainWindow::OnUpdateProgress(qint64 readBytes, qint64 totalBytes) { int valuePercent static_castint((readBytes * 100)/totalBytes); ui-progressBar-setValue(valuePercent); ui-progressBar-setFormat(QString::fromUtf8(当前进度为%1%).arg(QString::number(valuePercent))); } void MainWindow::OnActionBackToParent() { ui-treeWidget-clear(); m_hashDirectory.clear(); QString path ui-txtPath-text(); path path.left(path.lastIndexOf(/)); if(path.isEmpty()) { ui-Back-setEnabled(false); m_ftp-cd(/); } else { m_ftp-cd(path); } m_ftp-list(); ui-txtPath-setText(path); } void MainWindow::OnActionUpload() { // 得到选择的文件的路径保存在字符串链表中 QStringList string_list QFileDialog::getOpenFileNames(this, tr(选择文件), , tr(Files (*)), nullptr, QFileDialog::DontUseNativeDialog); if (string_list.isEmpty()) return; for (int i 0; i string_list.count(); i) { QString filePath; filePath string_list.at(i); QFile* uploadFile new QFile(filePath); if(!uploadFile-open(QIODevice::ReadOnly)) continue; QString fileName filePath.mid(filePath.lastIndexOf(/) 1); QString uploadPath ui-txtPath-text() / fileName; ui-progressBar-setValue(0); //uploadPath QString::fromLatin1(uploadPath.toLocal8Bit());//可以解决中文乱码 m_ftp-put(uploadFile,uploadPath); } ui-List-triggered(); } void MainWindow::OnActionDowload() { if(ui-treeWidget-selectedItems().count() 0) { OperationInfo(请选择要下载的文件,QMessageBox::Information); return; } QString fileName ui-treeWidget-currentItem()-text(0); QString folderPath QFileDialog::getSaveFileName(this,tr(保存文件),,,nullptr,QFileDialog::DontUseNativeDialog); QFile* downloadFile new QFile(folderPath); downloadFile-open(QIODevice::WriteOnly); ui-progressBar-setValue(0); m_ftp-get(fileName,downloadFile); } void MainWindow::OnActionList() { ui-treeWidget-clear(); m_hashDirectory.clear(); m_ftp-list(); } void MainWindow::OnActionNewFile() { AddNewFloderDialog dialog(this); if(dialog.exec() QDialog::Accepted){ QString folderName dialog.GetFolderName(); if(folderName.isEmpty()) folderName New Folder; m_ftp-mkdir(ui-txtPath-text() / folderName); ui-List-triggered(); } } void MainWindow::OnActionRemove() { if(ui-treeWidget-selectedItems().count() 0) { OperationInfo(请选择要删除的文件,QMessageBox::Information); return; } QString fileName ui-treeWidget-currentItem()-text(0); if(m_hashDirectory[fileName]){ m_ftp-rmdir(ui-txtPath-text() / fileName); } else{ m_ftp-remove(ui-txtPath-text() / fileName); } ui-List-triggered(); } void MainWindow::OnTreeWidgetItemActived(QTreeWidgetItem *item, int column) { QString name item-text(0); if(m_hashDirectory.value(name)) { ui-treeWidget-clear(); m_hashDirectory.clear(); QString filePath ui-txtPath-text(); filePath / name; m_ftp-cd(filePath); m_ftp-list(); ui-Back-setEnabled(true); ui-txtPath-setText(filePath); } } void MainWindow::OnMenuRequest(const QPoint pos) { QTreeWidgetItem* pItem ui-treeWidget-itemAt(pos); QMenu* pMenu new QMenu(this); //右键点击空白位置 if(pItem nullptr){ QAction* pBack pMenu-addAction(上一级); if(ui-txtPath-text().isEmpty()) pBack-setEnabled(false); QAction* pUpload pMenu-addAction(上传); QAction* pNewFolder pMenu-addAction(新建); connect(pBack,QAction::triggered,this,MainWindow::OnActionBackToParent); connect(pUpload,QAction::triggered,this,MainWindow::OnActionUpload); connect(pNewFolder,QAction::triggered,this,MainWindow::OnActionNewFile); } //点击选择Item else{ QAction* pDownLoad pMenu-addAction(下载); QAction* pDelete pMenu-addAction(删除); connect(pDownLoad,QAction::triggered,this,MainWindow::OnActionDowload); connect(pDelete,QAction::triggered,this,MainWindow::OnActionRemove); } //校正鼠标点的位置保证菜单出现在鼠标点击的位置 QPoint localPnt ui-treeWidget-viewport()-mapToGlobal(pos); pMenu-exec(localPnt); }完整工程项目地址使用QFtp类实现FTP客户端基本功能包括登录、上传、下载、删除、创建文件夹、返回等基础功能资源-CSDN文库