由于Qt5.0已经取消了qftp库,但是还在维护,我们可以下载下来使用。
下载链接https://github.com/qt/qtftp.git
一、效果展示
二、源码实现
ftpWidget.h
#ifndef FTPWIDGET_H #define FTPWIDGET_H #include#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "qftp.h" #include "qurlinfo.h" #define BTN_LOGIN_ICON ":/icon/image/iconLogin.png" #define BTN_QUIT_ICON ":/icon/image/iconQuit.png" #define BTN_UPLOAD_ICON ":/icon/image/iconUpload.png" #define BTN_DOWNLOAD_ICON ":/icon/image/iconDownload.png" #define BTN_BACK_ICON ":/icon/image/iconBack.png" #define ACTION_INNER_ICON ":/icon/image/iconInner.png" #define ACTION_DOWNLOAD_ICON ":/icon/image/iconDownload.png" #define ACTION_UPLOAD_ICON ":/icon/image/iconUpload.png" #define ACTION_BACK_ICON ":/icon/image/iconBack.png" #define TYPE_FILE_ICON ":/icon/image/iconFile (1).png" #define TYPE_FOLDER_ICON ":/icon/image/iconFolder.png" class FtpWidget : public QWidget { Q_OBJECT public: explicit FtpWidget(QWidget *parent = nullptr); bool set_login_para(QString ip,quint16 port,QString userName,QString userPassword); signals: protected: void closeEvent(QCloseEvent *e) override; private slots: void btn_click_slot(); void process_item_slot(QTreeWidgetItem *item, int column); void ftp_fommand_finished_slot(int commandId, bool error); void add_to_list_slot(const QUrlInfo &urlInfo); void update_transfer_progress_slot(qint64 readBytes, qint64 totalBytes); void cd_to_parent_slot(); void upload_file_dialog_select_slot(const QString &filePathName); void treewidget_item_clicked_slot(QTreeWidgetItem *item, int column); void treewidget_custom_menu_slot(const QPoint &pos); void action_trigged_slot(); private: void value_init(); void control_init(); void download_file(); void upload_file(); void cancel_download(); private: QGridLayout *gridLayout; QHBoxLayout *horizontalLayout; QPushButton *btnLogin; QPushButton *btnQuit; QPushButton *btnUpload; QPushButton *btnDownload; QPushButton *btnBack; QProgressBar *progressBar; QTreeWidget *treeWidget; QMenuBar *menubar; QLineEdit *lineEditPath; QString loginIp; quint16 loginPort; QString loginUserName; QString loginUserPassword; QHash isDirectory; QString currentPath; QFtp *ftp = nullptr; QFile *file = nullptr; QFileDialog *uploadFileDialog; QMenu *menuCustomer; QAction *actInter; QAction *actDownload; QAction *actUpload; QAction *actBack; }; #endif // FTPWIDGET_H
ftpWidget.cpp
#include "ftpwidget.h" #includeFtpWidget::FtpWidget(QWidget *parent) : QWidget{parent} { this->value_init(); this->control_init(); } void FtpWidget::value_init() { this->uploadFileDialog = new QFileDialog; this->uploadFileDialog->setModal(false); // uploadFileDialog->setAttribute(Qt::WA_DeleteOnClose); this->uploadFileDialog->setFileMode(QFileDialog::ExistingFile); //uploadFileDialog->show(); connect(this->uploadFileDialog,&QFileDialog::fileSelected,this,&FtpWidget::upload_file_dialog_select_slot); } void FtpWidget::control_init() { this->setObjectName(QString::fromUtf8("FtpWidget")); this->resize(800, 600); this->setWindowTitle(tr("下位机文件管理")); this->gridLayout = new QGridLayout(); this->gridLayout->setObjectName(QString::fromUtf8("gridLayout")); this->horizontalLayout = new QHBoxLayout(); this->horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout")); this->btnLogin = new QPushButton(); this->btnLogin->setObjectName(QString::fromUtf8("btnLogin")); this->btnLogin->setText(tr("登录")); this->horizontalLayout->addWidget(this->btnLogin); this->btnQuit = new QPushButton(); this->btnQuit->setObjectName(QString::fromUtf8("btnQuit")); this->btnQuit->setText(tr("退出")); this->horizontalLayout->addWidget(this->btnQuit); this->btnUpload = new QPushButton(); this->btnUpload->setObjectName(QString::fromUtf8("btnUpload")); this->btnUpload->setText(tr("上传")); this->horizontalLayout->addWidget(this->btnUpload); this->btnDownload = new QPushButton(); this->btnDownload->setObjectName(QString::fromUtf8("btnDownload")); this->btnDownload->setText(tr("下载")); this->horizontalLayout->addWidget(this->btnDownload); this->btnBack = new QPushButton(); this->btnBack->setObjectName(QString::fromUtf8("btnBack")); this->btnBack->setText(tr("上一级")); this->horizontalLayout->addWidget(this->btnBack); this->gridLayout->addLayout(this->horizontalLayout, 3, 0, 1, 1); this->progressBar = new QProgressBar(); this->progressBar->setObjectName(QString::fromUtf8("progressBar")); this->progressBar->setValue(0); this->progressBar->setAlignment(Qt::AlignCenter); this->gridLayout->addWidget(this->progressBar, 2, 0, 1, 1); this->lineEditPath = new QLineEdit(); this->lineEditPath->setReadOnly(true); this->gridLayout->addWidget(this->lineEditPath, 1, 0, 1, 1); this->treeWidget = new QTreeWidget(); this->treeWidget->setObjectName(QString::fromUtf8("treeWidget")); this->gridLayout->addWidget(this->treeWidget, 0, 0, 1, 1); this->setLayout(this->gridLayout); //控件设置值 this->btnQuit->setEnabled(false); this->btnUpload->setEnabled(false); this->btnDownload->setEnabled(false); this->btnBack->setEnabled(false); this->btnLogin->setIcon(QIcon(BTN_LOGIN_ICON)); this->btnQuit->setIcon(QIcon(BTN_QUIT_ICON)); this->btnUpload->setIcon(QIcon(BTN_UPLOAD_ICON)); this->btnDownload->setIcon(QIcon(BTN_DOWNLOAD_ICON)); this->btnBack->setIcon(QIcon(BTN_BACK_ICON)); // this ->treeWidget -> setEnabled(false); this ->treeWidget -> setRootIsDecorated(false); this ->treeWidget -> setHeaderLabels(QStringList() << tr("文件名") << tr("尺寸") << tr("所有者") << tr("组") << tr("时间")); this ->treeWidget -> header() ->setStretchLastSection(false); this->treeWidget->setContextMenuPolicy(Qt::CustomContextMenu); this->menuCustomer = new QMenu; this->actInter = new QAction(tr("进入")); this->actDownload = new QAction(tr("下载")); this->actUpload = new QAction(tr("上传")); this->actBack = new QAction(tr("回退")); this->actInter->setEnabled(false); this->actDownload->setEnabled(false); this->actUpload->setEnabled(false); this->actBack->setEnabled(false); this->actInter->setIcon(QIcon(ACTION_INNER_ICON)); this->actDownload->setIcon(QIcon(ACTION_DOWNLOAD_ICON)); this->actUpload->setIcon(QIcon(ACTION_UPLOAD_ICON)); this->actBack->setIcon(QIcon(ACTION_BACK_ICON)); this->menuCustomer->addAction(this->actInter); this->menuCustomer->addAction(this->actDownload); this->menuCustomer->addAction(this->actUpload); this->menuCustomer->addAction(this->actBack); connect(this->actInter,&QAction::triggered,this,&FtpWidget::action_trigged_slot); connect(this->actDownload,&QAction::triggered,this,&FtpWidget::action_trigged_slot); connect(this->actUpload,&QAction::triggered,this,&FtpWidget::action_trigged_slot); connect(this->actBack,&QAction::triggered,this,&FtpWidget::action_trigged_slot); connect(this->treeWidget, &QTreeWidget::itemActivated,this, &FtpWidget::process_item_slot); connect(this->treeWidget, &QTreeWidget::itemClicked,this, &FtpWidget::treewidget_item_clicked_slot); connect(this->treeWidget, &QTreeWidget::customContextMenuRequested,this, &FtpWidget::treewidget_custom_menu_slot); // connect(ui->treeWidget_fileList, &QTreeWidget::currentItemChanged,this, &FtpWidget::enableDownloadButton); //连接信号与槽 connect(this->btnLogin,&QPushButton::clicked,this,&FtpWidget::btn_click_slot); connect(this->btnQuit,&QPushButton::clicked,this,&FtpWidget::btn_click_slot); connect(this->btnUpload,&QPushButton::clicked,this,&FtpWidget::btn_click_slot); connect(this->btnDownload,&QPushButton::clicked,this,&FtpWidget::btn_click_slot); connect(this->btnBack,&QPushButton::clicked,this,&FtpWidget::btn_click_slot); } bool FtpWidget::set_login_para(QString ip, quint16 port, QString userName, QString userPassword) { if(ip == nullptr || port == 0 ||port>65535 ||userName == nullptr ||userPassword == nullptr) return false; this->loginIp = ip; this->loginPort = port; this->loginUserName = userName; this->loginUserPassword = userPassword; return true; } void FtpWidget::download_file() { if(this->file !=nullptr) { QMessageBox *messageBox = new QMessageBox; messageBox->setModal(false); messageBox->setIcon(QMessageBox::Critical); messageBox->setText(tr("请等待动作执行完成!")); messageBox->setAttribute(Qt::WA_DeleteOnClose); messageBox->show(); return; } QString fileName = this->treeWidget->currentItem()->text(0).toUtf8(); qDebug()< QMessageBox *messageBox = new QMessageBox; messageBox->setModal(false); messageBox->setIcon(QMessageBox::Information); messageBox->setText(tr("此文件已经存在!")); messageBox->setAttribute(Qt::WA_DeleteOnClose); messageBox->show(); return; } file = new QFile(fileName); if (!file->open(QIODevice::WriteOnly)) { QMessageBox *messageBox = new QMessageBox; messageBox->setModal(false); messageBox->setIcon(QMessageBox::Critical); messageBox->setText(tr("文件打开失败!")); messageBox->setAttribute(Qt::WA_DeleteOnClose); messageBox->show(); delete file; file = nullptr; return; } this->progressBar->setValue(0); ftp->get(QString::fromLatin1(this->treeWidget->currentItem()->text(0).toLocal8Bit()), file); } void FtpWidget::upload_file() { if(this->file !=nullptr) { QMessageBox *messageBox = new QMessageBox; messageBox->setModal(false); messageBox->setIcon(QMessageBox::Critical); messageBox->setText(tr("请等待动作执行完成!")); messageBox->setAttribute(Qt::WA_DeleteOnClose); messageBox->show(); return; } if(!uploadFileDialog->isHidden()) return; this->uploadFileDialog->show(); } void FtpWidget::cancel_download() { ftp->abort(); if (file->exists()) { file->close(); file->remove(); } delete file; this->file = nullptr; } void FtpWidget::btn_click_slot() { QPushButton *btn = qobject_cast (sender()); if(btn == this->btnLogin) { if(this->loginIp == nullptr || this->loginPort == 0 ||this->loginPort>65535 ||this->loginUserName == nullptr ||this->loginUserPassword == nullptr) return; ftp = new QFtp(this); connect(ftp, &QFtp::commandFinished,this, &FtpWidget::ftp_fommand_finished_slot); connect(ftp, &QFtp::listInfo,this, &FtpWidget::add_to_list_slot); connect(ftp, &QFtp::dataTransferProgress,this, &FtpWidget::update_transfer_progress_slot); this->treeWidget ->clear(); currentPath.clear(); isDirectory.clear(); ftp -> connectToHost(this->loginIp,21); ftp -> login(this->loginUserName,this->loginUserPassword); } else if(btn == this->btnQuit) { this->ftp->abort(); this->ftp->close(); delete this->ftp; this->ftp = nullptr; this->treeWidget->clear(); this->btnLogin->setEnabled(true); this->btnQuit->setEnabled(false); this->btnUpload->setEnabled(false); this->btnDownload->setEnabled(false); this->btnBack->setEnabled(false); this->actInter->setEnabled(false); this->actDownload->setEnabled(false); this->actUpload->setEnabled(false); this->actBack->setEnabled(false); } else if(btn == this->btnUpload) { this->upload_file(); } else if(btn == this->btnDownload) { this->download_file(); } else if(btn == this->btnBack) { this->cd_to_parent_slot(); } } void FtpWidget::process_item_slot(QTreeWidgetItem *item, int column) { QString name = item->text(0); if (isDirectory.value(name)) { qDebug()< treeWidget->clear(); isDirectory.clear(); currentPath += '/'; currentPath += name; ftp->cd(QString::fromLatin1(currentPath.toLocal8Bit())); ftp->list(); this->btnBack->setEnabled(true); this->actBack->setEnabled(true); this->lineEditPath->setText(this->currentPath.toUtf8()); return; } this->lineEditPath->setText(this->currentPath.toUtf8()); } void FtpWidget::ftp_fommand_finished_slot(int commandId, bool error) { // qDebug()< currentCommand() == QFtp::ConnectToHost) { if (error) { QMessageBox *messageBox = new QMessageBox; messageBox->setModal(false); messageBox->setIcon(QMessageBox::Critical); messageBox->setText(tr("连接服务器失败!")); messageBox->setAttribute(Qt::WA_DeleteOnClose); messageBox->show(); this->btnLogin->setEnabled(true); this->btnQuit->setEnabled(false); this->btnUpload->setEnabled(false); this->btnDownload->setEnabled(false); this->btnBack->setEnabled(false); this->actBack->setEnabled(false); this->actInter->setEnabled(false); this->actDownload->setEnabled(false); this->actUpload->setEnabled(false); this->actBack->setEnabled(false); // connectOrDisconnect(); return; } else { this->btnLogin->setEnabled(false); this->btnQuit->setEnabled(true); this->btnUpload->setEnabled(true); //this->btnDownload->setEnabled(true); this->btnBack->setEnabled(true); this->actBack->setEnabled(true); this->actInter->setEnabled(false); this->actDownload->setEnabled(false); this->actUpload->setEnabled(true); this->actBack->setEnabled(false); return; } } else if (ftp->currentCommand() == QFtp::Close) { this->btnLogin->setEnabled(true); this->btnQuit->setEnabled(false); this->btnUpload->setEnabled(false); this->btnDownload->setEnabled(false); this->btnBack->setEnabled(false); this->actBack->setEnabled(false); } if (ftp->currentCommand() == QFtp::Login) ftp->list(); if (ftp->currentCommand() == QFtp::Get) { if (error) { file->close(); file->remove(); QMessageBox *messageBox = new QMessageBox; messageBox->setModal(false); messageBox->setIcon(QMessageBox::Critical); messageBox->setText(tr("文件下载失败!")); messageBox->setAttribute(Qt::WA_DeleteOnClose); messageBox->show(); } else { this->progressBar ->setValue(100); file->close(); QMessageBox *messageBox = new QMessageBox; messageBox->setModal(false); messageBox->setIcon(QMessageBox::Information); messageBox->setText(tr("文件下载成功!")); messageBox->setAttribute(Qt::WA_DeleteOnClose); messageBox->show(); } delete file; this->file = nullptr; // enableDownloadButton(); } else if(ftp->currentCommand() == QFtp::Put) { if (error) { file->close(); file->remove(); QMessageBox *messageBox = new QMessageBox; messageBox->setModal(false); messageBox->setIcon(QMessageBox::Critical); messageBox->setText(tr("文件上传失败!")); messageBox->setAttribute(Qt::WA_DeleteOnClose); messageBox->show(); } else { this->progressBar ->setValue(100); file->close(); QMessageBox *messageBox = new QMessageBox; messageBox->setModal(false); messageBox->setIcon(QMessageBox::Information); messageBox->setText(tr("文件上传成功!")); messageBox->setAttribute(Qt::WA_DeleteOnClose); messageBox->show(); } delete file; this->file = nullptr; } else if (ftp->currentCommand() == QFtp::List) { if (isDirectory.isEmpty()) { this->treeWidget -> addTopLevelItem(new QTreeWidgetItem(QStringList() << tr(" "))); // this->treeWidget -> setEnabled(false); } } } void FtpWidget::add_to_list_slot(const QUrlInfo &urlInfo) { QTreeWidgetItem *item = new QTreeWidgetItem; item->setText(0, urlInfo.name().toLatin1()); item->setText(1, QString::number(urlInfo.size())); item->setText(2, urlInfo.owner().toLatin1()); item->setText(3, urlInfo.group().toLatin1()); item->setText(4, urlInfo.lastModified().toString("yyyy-MM-dd")); QPixmap pixmap(urlInfo.isDir() ? TYPE_FOLDER_ICON : TYPE_FILE_ICON); item->setIcon(0, pixmap); isDirectory[urlInfo.name().toLatin1()] = urlInfo.isDir(); this->treeWidget->addTopLevelItem(item); if (!this ->treeWidget->currentItem()) { this ->treeWidget->setCurrentItem(this ->treeWidget->topLevelItem(0)); //this ->treeWidget->setEnabled(true); } } void FtpWidget::cd_to_parent_slot() { this->treeWidget -> clear(); isDirectory.clear(); currentPath = currentPath.left(currentPath.lastIndexOf('/')); if (currentPath.isEmpty()) { this->btnBack->setEnabled(false); this->actBack->setEnabled(false); ftp->cd("/"); } else { ftp->cd(QString::fromLatin1(currentPath.toLocal8Bit())); } ftp->list(); this->lineEditPath->setText(this->currentPath.toUtf8()); } void FtpWidget::upload_file_dialog_select_slot(const QString &filePathName) { qDebug()< open(QIODevice::ReadOnly)) return; QString uploadPath; // 解决中文乱码问题 QString name = filePathName.mid(filePathName.lastIndexOf("/") + 1); uploadPath = QString("%1/%2").arg(currentPath).arg(name); this->progressBar->setValue(0); ftp->put(file, QString::fromLatin1(uploadPath.toLocal8Bit())); } void FtpWidget::treewidget_item_clicked_slot(QTreeWidgetItem *item, int column) { Q_UNUSED(item) Q_UNUSED(column) this->lineEditPath->setText(this->currentPath.toUtf8()); QString name = item->text(0); if (isDirectory.value(name)) { this->btnDownload->setEnabled(false); this->actInter->setEnabled(true); this->actDownload->setEnabled(false); } else { this->btnDownload->setEnabled(true); this->actInter->setEnabled(false); this->actDownload->setEnabled(true); } } void FtpWidget::treewidget_custom_menu_slot(const QPoint &pos) { Q_UNUSED(pos) this->menuCustomer->exec(this->treeWidget->cursor().pos()); } void FtpWidget::action_trigged_slot() { QAction *act = qobject_cast (sender()); if(act == this->actInter) { this->process_item_slot(this->treeWidget->currentItem(),0); } else if(act == this->actDownload) { this->download_file(); } else if(act == this->actUpload) { this->upload_file(); } else if(act == this->actBack) { this->cd_to_parent_slot(); } } void FtpWidget::update_transfer_progress_slot(qint64 readBytes, qint64 totalBytes) { this->progressBar->setValue(static_cast (readBytes/totalBytes)); } void FtpWidget::closeEvent(QCloseEvent *e) { if(this->file != nullptr) return; if(this->ftp != nullptr) { this->ftp->abort(); this->ftp->close(); delete this->ftp; } }
三、完整工程下载
完整工程链接



