【问题标题】:Qt, QCoreApplication and QFtpQt、QCoreApplication 和 QFtp
【发布时间】:2015-03-24 13:19:29
【问题描述】:

我想第一次使用 QFtp,并在 Google 上搜索了很多以了解应该如何使用它。这是一个典型的例子:

#include <QCoreApplication>
#include <QFtp>
#include <QFile>

int main(int argc, char ** argv)
{
  QCoreApplication app(argc, argv);

  QFile *file = new QFile( "C:\\Devel\\THP\\tmp\\test.txt" );
  file->open(QIODevice::ReadWrite);

  QFtp *ftp = new QFtp();

  ftp->setTransferMode(QFtp::Active);
  ftp->connectToHost("ftp.trolltech.com"); 
  ftp->login();                           
  ftp->cd("qt");                     
  ftp->get("INSTALL",file);               
  ftp->close();

  QObject::connect(ftp, SIGNAL(done(bool)), &app, SLOT(quit()));

  int ret = app.exec();

  delete ftp;
  delete file;

  return ret;
}

问题:

据我了解,需要 QCoreApplication 应用程序来处理“完成”信号,该信号在 ftp-get 完成时发出。现在,ftp-&gt;get 在连接之前被调用,甚至在应用程序处理程序运行之前调用(app.exec() 之后被调用)。

如果文件传输在“connect”语句之前已经完成,会发生什么?事实上,这不会发生,但我可以在ftp-&gt;close() 和 connect(...) 之间设置一个人为的延迟,比如 1 分钟。在此期间,ftp get 肯定会完成。会发生什么?

【问题讨论】:

  • 如果 ftp 在事件循环开始之前完成,您的应用程序将不会退出,您将不得不终止其进程。
  • QFtp 需要一个正在运行的事件循环来处理命令。因此,您可以在 connect 语句之前等待 10 000 年,这没有什么区别,因为您告诉 QFtp 执行的命令在您调用 app.exec(); 之前不会被执行

标签: qt signals slot qftp


【解决方案1】:

请注意,QFtp 仅适用于旧版 Qt 应用程序,现在建议使用 QNetworkAccessManagerQNetworkReply,如 Qt documentation 中所述。

话虽如此,由于您的 connect 调用位于连接到 FTP 站点并检索文件之后,如果首先下载文件,则永远不会达到“退出”信号。如果您在创建 QFtp 对象后直接建立连接,那么这将不是问题:-

QFtp *ftp = new QFtp();
QObject::connect(ftp, SIGNAL(done(bool)), &app, SLOT(quit()));

这保证了当 QFtp 对象发出“完成”信号时将调用“退出”槽。

QFtp *ftp = new QFtp();
QObject::connect(ftp, SIGNAL(done(bool)), &app, SLOT(quit()));

ftp->setTransferMode(QFtp::Active);
ftp->connectToHost("ftp.trolltech.com"); 
ftp->login();                           
ftp->cd("qt");                     
ftp->get("INSTALL",file);               
ftp->close();

int ret = app.exec();

但实际上,我希望您的示例中的连接会在机器有时间协商与另一台服务器的连接、登录并开始下载文件之前完成。

【讨论】:

  • 请注意,Qt 不会处理信号/槽之前 app.exec(); 已调用以启动事件循环。
  • @vahancho,是的,这就是为什么我建议使用具有零超时的 QTimer 以确保 FTP 进程在主事件循环开始后发生,或者我在这里遗漏了什么?
  • QFtp uses QTimer::singleshot internally 用于每个命令。 QFtp 在事件循环开始之前什么都不做。所以延迟QFtp及其命令的创建是不必要的。
  • @thuga,很好,感谢您指出。我已经相应地更新了答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-21
  • 1970-01-01
  • 2021-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多