QT5编译使用QFtp

背景

使用 QNetworkAccessManager 可以实现 Ftp 的上传/下载功能,但它没有提供例如list、cd、remove、mkdir、rmdir、rename 等功能。这种情况下,我们可以使用QFtp,需要下载源码、编译并处理一些坑。

下载

从 GitHub 下载 QFtp:

https://github.com/qt/qtftp

编译

  • 修改 qftp/qftp.pro,删除最后一行,module_qtftp_tests。不然编译会有错误,这个是测试子项目,暂时去除,先编译使用。
  • 修改 qftp/src/qftp/qftp.h 第47行 #include <QtFtp/qurlinfo.h> => #include <qurlinfo.h>
  • 修改 qftp/src/qftp/qftp.pro 第4,5行的+,-号互换,生成*.dll
  • 修改第4行为 CONFIG += staticlib,生成.lib和.prl

用qtcreator打开qftp/qftp.pro,编译生成库文件。

放入QT5安装目录中

我以Qt5.5.1为例说明,其它版本类似

  • 将 Qt5Ftpd.lib、Qt5Ftp.lib、Qt5Ftpd.prl、Qt5Ftp.prl 拷贝至 D:\Qt\Qt5.5.1\5.5\msvc2010\lib。
  • 将Qt5Ftpd.dll、Qt5Ftp.dll 拷贝至D:\Qt\Qt5.5.1\5.5\msvc2010\bin。
  • 将qftp.h、qurlinfo.h 拷贝至 D:\Qt\Qt5.5.1\5.5\msvc2010\include\QtNetwork,并新建一个名为 QFtp 的文件(没有后缀名),然后用本写入 #include "qftp.h"

运行示例项目

  1. 作为qftp/qftp.pro 项目的子项目,直接编译examples项目,只需要更改qftp\examples\qftp\ftpwindow.cpp中的43行,将#include <QtFtp>改为#include <QFtp>,即可以编译并运行。
  2. 作为独立项目,除了修改1中的这项,还需要修改qftp\examples\qftp\qftp.pro中ftp库的加载方式,从第五行中删除ftp,然后增加如下代码:
CONFIG(debug, debug|release) {
   LIBS += -lQt5Ftpd
} else {
   LIBS += -lQt5Ftp
}

也就是说,ftp的加载方式还不能与Qt5的原生库完全一致,如何做到这一点,我还需要时间研究。

示例项目改进

修正进度条的提前显示,对progressDialog新对象进行如下设置,去掉了取消操作,取消操作有问题,暂时屏蔽。

 progressDialog = new QProgressDialog("download...", nullptr, 0, 100, this);
 progressDialog->setWindowModality(Qt::WindowModal);
 auto winFlags = windowFlags() & ~Qt::WindowMinMaxButtonsHint;
 progressDialog->setWindowFlags(winFlags &~ Qt::WindowCloseButtonHint); //去掉窗口的默认按钮
 progressDialog->reset();                   //避免提前显示
 progressDialog->setAutoClose(false);
 progressDialog->setAutoReset(false);

屏蔽取消按钮的消息链接。

//connect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelDownload()));

支持多文件下载
首先,在QTreeWidget生成后,设置其可以选中多行。

fileList->setSelectionMode(QAbstractItemView::ExtendedSelection);

修改downloadFile函数,支持多文件下载。

QList<QTreeWidgetItem*> selectedItemList = fileList->selectedItems();
for (int i = 0; i < selectedItemList.size(); i++)
 {
    QString fileName = selectedItemList[i]->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(fileName, file);
    progressDialog->setLabelText(tr("Downloading %1...").arg(fileName));
    downloadButton->setEnabled(false);
    progressDialog->exec();
}

项目地址

https://github.com/zhoutk/qtDemo

命令行编译

git clone https://github.com/zhoutk/qtDemo
cd qtDemo/qftp & mkdir build & cd build
cmake ..
cmake --build .      

编译时注意:cmake默认为x86架构,需要与你安装的Qt版本对应;编译好了,运行前,请注意目录结构是否正确。

小结

上面是正统方法在qt5中使用qftp,还可以直接把其源代码纳入你的应用项目中,因为一共只有四个文件,稍作修改就可以使用。我发现该项目的问题,主要是cancelDownload会出让程序崩溃,感觉问题出在本地文件已经被清除,还有后续的数据到来,结果就异常了。有时间再来研究,看能不能把协议学透,自己造个轮子出来。


全栈编程
自由程序员,技术路线c,delphi, c++,c#,java,php,node.js,python,golang,typescript;超喜欢re...

自由程序员,技术路线c,delphi,c++,c#,java,php,node.js,python,golang,typescript;超喜欢rea...

2.6k 声望
1.2k 粉丝
0 条评论
推荐阅读
node.js基于 cmake-js 进行插件开发实战
以前工作在node.js环境下,做微服务产品; 三年前转回到C++环境,已经有一些代码积攒。我将以往基于node.js与C++的相关项目结合起来(C++代码以addon插件嵌入),实现了一个微服务快速(rest api service)开发框...

zhoutk阅读 797

麒麟操作系统 (kylinos) 从入门到精通 - 研发环境 - 第二十一篇 C++/C语言开发环境搭建
类别:笔记本型号:中国长城 NF14C硬件平台:飞腾处理器(ArmV8 指令集)系统:银河麒麟操作系统 V10 SP1(2203) 关键词:信创,麒麟系统,linux,c++,c,内核飞腾,arm

码上世界1阅读 2.4k评论 1

封面图
万字避坑指南!C++的缺陷与思考(下)
导读 | 在万字避坑指南!C++的缺陷与思考(上)一文中,微信后台开发工程师胡博豪,分享了C++的发展历史、右值引用与移动语义、类型说明符等内容,深受广大开发者喜爱!此篇,我们邀请作者继续总结其在C++开发过...

腾讯云开发者5阅读 495评论 1

DBoS 系统说明
程序员TianSong以单片机开发入门,后续又做了 Qt 相关工作,有时间后开始进行 linux 相关的学习,恰巧在二一年十一月份,百问网的韦东山老师进行了三个月的 linux 驱动直播,于是有了开发 DBoS 的念头。

TianSong1阅读 1.1k

【Qt】简单桌面
[链接]简介简单桌面是一款小巧便捷的桌面背景管理软件。由编程爱好者个人开发,不收集使用者个人信息、不连接网络、不弹窗。下载功能支持单静态图片及多静态图片轮播(轮播时间可设置)支持GIF动画背景支持视频背...

TianSong3阅读 2.1k

在vs2022中对于QT5的简单使用
背景vs2022配置了QT5.14.2,然后尝试手写了一下qt程序,问题遇到的问题如下1.新建程序的时候,如果选择了类型为widget程序vs就默认启用qt creator的接口,生成ui文件而我不想用ui直接手写,所以需要创建qt empty ...

乐码客阅读 964

一种将函数模板定义和声明分开的方法
&emsp;&emsp;在 C++ 中为了操作简洁引入了函数模板。所谓的函数模板实际上是建立一个通用函数,其函数类型或形参类型不具体指定,用一个虚拟的类型来表达,这个通用函数就称为函数模板。

Sharemaker阅读 869

封面图

自由程序员,技术路线c,delphi,c++,c#,java,php,node.js,python,golang,typescript;超喜欢rea...

2.6k 声望
1.2k 粉丝
宣传栏