陈广荣 發表於 2026-1-5 09:03:11

QT5使用QFtp的详细步骤

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li>1、QFtp编译</li><ul class="second_class_ul"><li>1.1 下载</li><li>1.2 修改</li><li>1.3 编译</li><li>1.4 部署</li><li>2.5 使用</li><ul class="third_class_ul"><li>客户端</li></ul></ul></ul></div><p class="maodian"></p><h2>1、QFtp编译</h2>
<p class="maodian"></p><h3>1.1 下载</h3>
<p>下载QFtp源码,https://github.com/qt/qtftp</p>
<div class="jb51code"><pre class="brush:bash;">git clone https://github.com/qt/qtftp.git
</pre></div>
<p class="maodian"></p><h3>1.2 修改</h3>
<p>打开qt工程,修改qftp.pro文件中框选的部分,修改为下图所示。修改qftp.h文件的qurlinfo.h头文件,改为下图,该头文件路径有问题</p>
<div class="jb51code"><pre class="brush:cpp;">CONFIG += static
CONFIG += shared
</pre></div>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010509032391.png" /></p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010509032358.png" /></p>
<p class="maodian"></p><h3>1.3 编译</h3>
<p>只构建src</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010509032385.png" /></p>
<p class="maodian"></p><h3>1.4 部署</h3>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010509032342.png" /></p>
<ul><li>创建一个文件夹&ldquo;qtftp&rdquo;</li><li>复制&ldquo; bin、lib、include&rdquo;文件夹至&ldquo;qtftp&rdquo;文件夹中</li><li>把源码 src中的头文件 复制到 include 文件夹中<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010509032359.png" /></p>lib
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010509032343.png" /></p>include
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202601/2026010509032331.png" /></p></li></ul>
<p class="maodian"></p><h3>2.5 使用</h3>
<p>在.pro中添加组件,然后程序包含头文件就行。</p>
<div class="jb51code"><pre class="brush:cpp;"># QT += ftp

LIBS += $$XLDFLAGS\
                -L/usr/qtftp/lib -lQt5Ftp

INCLUDEPATH += /usr/qtftp/include
</pre></div>
<div class="jb51code"><pre class="brush:cpp;">#include &lt;QFtp&gt;
</pre></div>
<p class="maodian"></p><h4>客户端</h4>
<div class="jb51code"><pre class="brush:cpp;">#ifndef FTPMANAGER_H
#define FTPMANAGER_H

#include &lt;QObject&gt;
//#include &lt;QFtp&gt;
#include &lt;QFile&gt;
//#include &lt;QUrlInfo&gt;
#include &lt;QTimer&gt;
#include &lt;QFileInfo&gt;
#include "qftp.h"

class FtpManager : public QObject
{
    Q_OBJECT

public:
    explicit FtpManager(QObject *parent = nullptr);
    void connectToHost(const QString&amp; host, int port, const QString&amp; user, const QString&amp; pass);
    void uploadFile(const QString&amp; fileName);
    void downloadFile(const QString&amp; remoteFile, const QString&amp; localFile);
    void uploadFolder(const QString &amp;localFolderPath, const QString &amp;remoteFolderPath);
    void deleteFile(const QString&amp; fileName);
    void listDirectory();
    void DelayMsec(unsigned int msec);
signals:
    void fileListUpdated(const QStringList&amp; files);
    void progressUpdated(int percent);
    void statusUpdated(const QString&amp; status);

private slots:
    void ftpCommandStarted(int id);
    void ftpCommandFinished(int id, bool error);
    void ftpListInfo(const QUrlInfo&amp; urlInfo);
    void ftpDataTransferProgress(qint64 done, qint64 total);

private:
    QFtp* m_ftp;
    QStringList m_fileList;
    QString m_currentLocalFile;
    QFile* m_file;
    QTimer* m_refreshTimer;
};

#endif // FTPMANAGER_H

</pre></div>
<div class="jb51code"><pre class="brush:cpp;">#include "ftpmanager.h"
#include &lt;QMessageBox&gt;
#include &lt;QApplication&gt;

FtpManager::FtpManager(QObject *parent)
    : QObject(parent)
    , m_ftp(new QFtp(this))
    , m_file(nullptr)
    , m_refreshTimer(new QTimer(this))
{
    connect(m_ftp, &amp;QFtp::commandStarted, this, &amp;FtpManager::ftpCommandStarted);
    connect(m_ftp, &amp;QFtp::commandFinished, this, &amp;FtpManager::ftpCommandFinished);
    connect(m_ftp, &amp;QFtp::listInfo, this, &amp;FtpManager::ftpListInfo);
    connect(m_ftp, &amp;QFtp::dataTransferProgress, this, &amp;FtpManager::ftpDataTransferProgress);

    connect(m_refreshTimer, &amp;QTimer::timeout, this, &amp;FtpManager::listDirectory);
    m_refreshTimer-&gt;setSingleShot(true);
}

void FtpManager::connectToHost(const QString&amp; host, int port, const QString&amp; user, const QString&amp; pass)
{
    emit statusUpdated("正在连接...");
    m_ftp-&gt;connectToHost(host, port);
    m_ftp-&gt;login(user, pass);
}

void FtpManager::uploadFile(const QString&amp; fileName)
{
    m_file = new QFile(fileName, this);
    if (!m_file-&gt;open(QIODevice::ReadOnly)) {
      emit statusUpdated("无法打开文件");
      return;
    }

    QString remoteName = QFileInfo(fileName).fileName();
    m_currentLocalFile = fileName;
    emit statusUpdated(QString("正在上传: %1").arg(remoteName));
    m_ftp-&gt;put(m_file, remoteName);
}

void FtpManager::uploadFolder(const QString &amp;localFolderPath, const QString &amp;remoteFolderPath) {
    QDir dir(localFolderPath);
    QFileInfoList entries = dir.entryInfoList(QDir::NoDotAndDotDot | QDir::Dirs | QDir::Files);
    QString remoteEntryPath = remoteFolderPath + "/"+dir.dirName();
    m_ftp-&gt;mkdir(remoteEntryPath);
    DelayMsec(1000);
    m_ftp-&gt;cd(remoteEntryPath);
    DelayMsec(2000);

    foreach (const QFileInfo &amp;entryInfo, entries) {
      QString localEntryPath = entryInfo.absoluteFilePath();

      remoteEntryPath += "/" + entryInfo.fileName();
      if (entryInfo.isFile()) { // 如果是文件,则上传文件
            uploadFile(localEntryPath);
            DelayMsec(100);
         // QFile file(localEntryPath);
         // if (file.open(QIODevice::ReadOnly)) {
               // m_ftp-&gt;put(&amp;file, remoteEntryPath); // 上传文件
               // DelayMsec(2000);

               // file.close();
         // }

      }
    }

}

void FtpManager::downloadFile(const QString&amp; remoteFile, const QString&amp; localFile)
{
    m_file = new QFile(localFile, this);
    if (!m_file-&gt;open(QIODevice::WriteOnly)) {
      emit statusUpdated("无法创建本地文件");
      return;
    }

    m_currentLocalFile = localFile;
    emit statusUpdated(QString("正在下载: %1").arg(remoteFile));
    m_ftp-&gt;get(remoteFile, m_file);
}

void FtpManager::deleteFile(const QString&amp; fileName)
{
    emit statusUpdated(QString("正在删除: %1").arg(fileName));
    m_ftp-&gt;remove(fileName);
}

void FtpManager::listDirectory()
{
    m_fileList.clear();
    m_ftp-&gt;list();
}

void FtpManager::ftpCommandStarted(int id)
{
    Q_UNUSED(id);
}

void FtpManager::ftpCommandFinished(int id, bool error)
{
    Q_UNUSED(id);

    if (error) {
      emit statusUpdated(QString("错误: %1").arg(m_ftp-&gt;errorString()));
      if (m_file &amp;&amp; m_file-&gt;isOpen()) {
            m_file-&gt;close();
            m_file-&gt;deleteLater();
            m_file = nullptr;
      }
      return;
    }

    switch (m_ftp-&gt;currentCommand()) {
    case QFtp::ConnectToHost:
      emit statusUpdated("连接成功");
      m_ftp-&gt;list();
      break;
    case QFtp::Login:
      emit statusUpdated("登录成功");
      m_ftp-&gt;list();
      break;
    case QFtp::List:
      emit fileListUpdated(m_fileList);
      emit statusUpdated("目录列表更新完成");
      break;
    case QFtp::Put:
      if (m_file) {
            m_file-&gt;close();
            m_file-&gt;deleteLater();
            m_file = nullptr;
      }
      emit statusUpdated("上传完成");
      m_refreshTimer-&gt;start(1000); // 延迟刷新
      break;
    case QFtp::Get:
      if (m_file) {
            m_file-&gt;close();
            m_file-&gt;deleteLater();
            m_file = nullptr;
      }
      emit statusUpdated("下载完成");
      break;
    case QFtp::Remove:
      emit statusUpdated("删除完成");
      m_refreshTimer-&gt;start(1000); // 延迟刷新
      break;
    default:
      break;
    }
}

void FtpManager::ftpListInfo(const QUrlInfo&amp; urlInfo)
{
    if (urlInfo.name() != "." &amp;&amp; urlInfo.name() != "..") {
      QString item = urlInfo.name();
      if (urlInfo.isDir()) {
            item += "/";
      }
      m_fileList &lt;&lt; item;
    }
}

void FtpManager::ftpDataTransferProgress(qint64 done, qint64 total)
{
    if (total &gt; 0) {
      int percent = static_cast&lt;int&gt;((done * 100) / total);
      emit progressUpdated(percent);
    }
}
void FtpManager::DelayMsec(unsigned int msec)
{
    QEventLoop loop;
    QTimer::singleShot(msec, &amp;loop, SLOT(quit()));
    loop.exec(); // 在这里会阻塞,直到QTimer超时退出循环

}

</pre></div>
<div class="jb51code"><pre class="brush:cpp;">#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include &lt;QMainWindow&gt;
#include &lt;QLabel&gt;
#include &lt;QDockWidget&gt;
#include &lt;QMenu&gt;
#include &lt;QSystemTrayIcon&gt;
#include &lt;QStyle&gt;


class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

protected:

private slots:


private:


};
#endif // MAINWINDOW_H

</pre></div>
<div class="jb51code"><pre class="brush:cpp;">#include "mainwindow.h"
#include &lt;QWidget&gt;
#include &lt;QVBoxLayout&gt;
#include &lt;QHBoxLayout&gt;
#include &lt;QLabel&gt;
#include &lt;QLineEdit&gt;
#include &lt;QPushButton&gt;
#include &lt;QListWidget&gt;
#include &lt;QProgressBar&gt;
#include &lt;QFileDialog&gt;
#include &lt;QMessageBox&gt;

#include "ftpmanager.h"



MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
      setWindowTitle("Qt5 QFtp客户端");
      resize(600, 500);

      // 创建FTP管理器
      FtpManager* ftpManager = new FtpManager(this);

      // 服务器设置区域
      QWidget* serverWidget = new QWidget(this);
      serverWidget-&gt;setFixedSize(500,50);

      QHBoxLayout* serverLayout = new QHBoxLayout(serverWidget);

      QLabel* hostLabel = new QLabel("主机:");
      QLineEdit* hostEdit = new QLineEdit("ftp.example.com");
      hostEdit-&gt;setObjectName("hostEdit");

      QLabel* portLabel = new QLabel("端口:");
      QLineEdit* portEdit = new QLineEdit("21");
      portEdit-&gt;setObjectName("portEdit");
      portEdit-&gt;setMaximumWidth(60);

      QLabel* userLabel = new QLabel("用户:");
      QLineEdit* userEdit = new QLineEdit("anonymous");
      userEdit-&gt;setObjectName("userEdit");

      QLabel* passLabel = new QLabel("密码:");
      QLineEdit* passEdit = new QLineEdit();
      passEdit-&gt;setObjectName("passEdit");
      passEdit-&gt;setEchoMode(QLineEdit::Password);

      QPushButton* connectBtn = new QPushButton("连接");
      connectBtn-&gt;setObjectName("connectBtn");

      serverLayout-&gt;addWidget(hostLabel);
      serverLayout-&gt;addWidget(hostEdit);
      serverLayout-&gt;addWidget(portLabel);
      serverLayout-&gt;addWidget(portEdit);
      serverLayout-&gt;addWidget(userLabel);
      serverLayout-&gt;addWidget(userEdit);
      serverLayout-&gt;addWidget(passLabel);
      serverLayout-&gt;addWidget(passEdit);
      serverLayout-&gt;addWidget(connectBtn);

      // 文件操作按钮
      QWidget* controlWidget = new QWidget(this);
      controlWidget-&gt;setFixedSize(500,50);
      controlWidget-&gt;move(0,45);
      QHBoxLayout* controlLayout = new QHBoxLayout(controlWidget);

      QPushButton* uploadBtn = new QPushButton("上传");
      uploadBtn-&gt;setObjectName("uploadBtn");
      QPushButton* downloadBtn = new QPushButton("下载");
      downloadBtn-&gt;setObjectName("downloadBtn");
      QPushButton* deleteBtn = new QPushButton("删除");
      deleteBtn-&gt;setObjectName("deleteBtn");
      QPushButton* refreshBtn = new QPushButton("刷新");
      refreshBtn-&gt;setObjectName("refreshBtn");

      controlLayout-&gt;addWidget(uploadBtn);
      controlLayout-&gt;addWidget(downloadBtn);
      controlLayout-&gt;addWidget(deleteBtn);
      controlLayout-&gt;addWidget(refreshBtn);
      controlLayout-&gt;addStretch();

      // 文件列表
      QListWidget* fileList = new QListWidget(this);
      fileList-&gt;setFixedSize(500,300);
      fileList-&gt;move(20,100);
      fileList-&gt;setObjectName("fileList");

      // 进度条
      QProgressBar* progressBar = new QProgressBar(this);
      progressBar-&gt;setObjectName("progressBar");
      progressBar-&gt;setVisible(false);

      // 状态标签
      QLabel* statusLabel = new QLabel("就绪",this);
      statusLabel-&gt;move(20,400);
      statusLabel-&gt;setObjectName("statusLabel");

      // 布局
      QVBoxLayout* mainLayout = new QVBoxLayout();
      mainLayout-&gt;addWidget(serverWidget);
      mainLayout-&gt;addWidget(controlWidget);
      mainLayout-&gt;addWidget(fileList);
      mainLayout-&gt;addWidget(progressBar);
      mainLayout-&gt;addWidget(statusLabel);

      this-&gt;setLayout(mainLayout);

      // 连接信号槽
      QObject::connect(connectBtn, &amp;QPushButton::clicked, [=]() {
            QString host = hostEdit-&gt;text();
            int port = portEdit-&gt;text().toInt();
            QString user = userEdit-&gt;text();
            QString pass = passEdit-&gt;text();
            ftpManager-&gt;connectToHost(host, port, user, pass);
      });

      QObject::connect(uploadBtn, &amp;QPushButton::clicked, [=]() {
            QString fileName = QFileDialog::getOpenFileName(this, "选择上传文件");
            if (!fileName.isEmpty()) {
                ftpManager-&gt;uploadFile(fileName);
            }
      });

      QObject::connect(downloadBtn, &amp;QPushButton::clicked, [=]() {
            QListWidgetItem* item = fileList-&gt;currentItem();
            if (item) {
                QString fileName = item-&gt;text();
                QString savePath = QFileDialog::getSaveFileName(this, "保存文件", fileName);
                if (!savePath.isEmpty()) {
                  ftpManager-&gt;downloadFile(fileName, savePath);
                }
            } else {
                QMessageBox::warning(this, "警告", "请选择要下载的文件");
            }
      });

      QObject::connect(deleteBtn, &amp;QPushButton::clicked, [=]() {
            QListWidgetItem* item = fileList-&gt;currentItem();
            if (item) {
                QString fileName = item-&gt;text();
                int ret = QMessageBox::question(this, "确认", QString("确定删除文件 %1?").arg(fileName));
                if (ret == QMessageBox::Yes) {
                  ftpManager-&gt;deleteFile(fileName);
                }
            } else {
                QMessageBox::warning(this, "警告", "请选择要删除的文件");
            }
      });

      QObject::connect(refreshBtn, &amp;QPushButton::clicked, [=]() {
            ftpManager-&gt;listDirectory();
      });

      QObject::connect(ftpManager, &amp;FtpManager::fileListUpdated, [=](const QStringList&amp; files) {
            fileList-&gt;clear();
            fileList-&gt;addItems(files);
      });

      QObject::connect(ftpManager, &amp;FtpManager::progressUpdated, [=](int percent) {
            progressBar-&gt;setVisible(true);
            progressBar-&gt;setValue(percent);
            if (percent &gt;= 100) {
                QTimer::singleShot(1000, [=]() {
                  progressBar-&gt;setVisible(false);
                });
            }
      });

      QObject::connect(ftpManager, &amp;FtpManager::statusUpdated, [=](const QString&amp; status) {
            statusLabel-&gt;setText(status);
      });




}

MainWindow::~MainWindow()
{
}


</pre></div>
<div class="jb51code"><pre class="brush:cpp;">#include &lt;QApplication&gt;
#include &lt;QWidget&gt;


#include "mainwindow.h"


int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    MainWindow mainWindow;

    mainWindow.show();

    return app.exec();
}

</pre></div>
<p>到此这篇关于QT5使用QFtp的详细步骤的文章就介绍到这了,更多相关QT5使用QFtp内容请搜索琼殿技术社区以前的文章或继续浏览下面的相关文章希望大家以后多多支持琼殿技术社区!</p>
<p></p>
                           
                            <div class="art_xg">
                              <b>您可能感兴趣的文章:</b><ul><li>QT5编译使用QFtp的方法步骤</li></ul>
                            </div>

                        </div>
                        <!--endmain-->
頁: [1]
查看完整版本: QT5使用QFtp的详细步骤