gpt4 book ai didi

qt - 关闭 QCoreApplication 的正确方法

转载 作者:行者123 更新时间:2023-12-02 05:59:58 30 4
gpt4 key购买 nike

我正在制作一个用于从 FTP 服务器下载文件的 Qt5 QCoreApplication(从 HTTP 开始,现在已切换)。

我的程序要关闭时遇到问题。在我将 exit(0) 添加到 downloader.cpp 后,我的程序现在结束了,但我收到以下错误:

QWaitCondition: Destroyed while threads are still waiting.

我的代码如下:

main.cpp

#include <QCoreApplication>
#include <downloader.h>

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);

Downloader d;
d.doDownload();

a.exec();
}


**downloader.cpp**

#include "downloader.h"

Downloader::Downloader(QObject *parent) :
QObject(parent)
{
}

void Downloader::doDownload() {

manager = new QNetworkAccessManager(this);
connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));

manager->get(QNetworkRequest(QUrl("ftp://ftp.fao.org/Public/GIEWS/windisp/40manual/wd4en.pdf")));
}


void Downloader::replyFinished (QNetworkReply *reply)
{

if(reply->error()) {
qDebug() << "ERROR!";
qDebug() << reply->errorString();
}
else

{
qDebug() << "Download finished!";

QFile *file = new QFile("C:/Users/jelicicm/Desktop/wd4en.pdf");

if(file->open(QFile::Append))
{
file->write(reply->readAll());
file->flush(); file->close();
qDebug() <<"Downloaded file size:" <<(file->size())/1024<<"KB";
}
delete file;
}

reply->deleteLater();
exit(0);

}

我得到以下输出:

Download Finished! Downloaded file size... QWaitCondition: Destroyed while threads are still waiting.

就我所注意到的,我想象的一切都实现了。下载文件,并显示其大小。但我想这个错误一定意味着什么。

有人可以向我解释这个错误是什么、为什么会发生以及如何修补它吗?

最佳答案

您的代码有一些问题。您将 Qt 视为本质上是过程性的,而实际上它是通过主循环由事件驱动的。

首先,在QApplication循环开始之前调用qApp->exit(0)是错误的。根据 Qt,“如果事件循环未运行,则此函数不执行任何操作。”您的事件循环尚未运行,因为您在调用 之前调用了 doDownload执行

其次,当您运行 QApplication::exec 时,您还没有创建任何顶级窗口或要调度的事件。我不确定当您调用 exec 没有任何工作要做时应该发生什么。当然,从语义上讲,对 exec 的调用什么也不做。从技术上讲……也许它会导致线程错误。同样,我不确定,但我知道您不应该以这种方式使用 exec

做所有你喜欢的Qt 事情之前运行你的主事件循环。这允许 Qt 调用您的代码。添加插槽 doDownload 和信号 finished 到您的 Downloader

class Downloader : public QObject 
{
Q_OBJECT

public:
Downloader(QObject * parent = nullptr);

private slots:
void doDownload();

signals:
void finished();
}

...

void Downloader::doDownload()
{
// Same implementation as before
// Emit signal when finished
emit finished();
}

然后在通过调用 exec 并启动主循环建立控制反转后调用您的插槽:

#include <QCoreApplication>
#include "Downloader.h"

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);

Downloader d;

// Quit application when work is finished
QObject::connect(&d, SIGNAL(finished()), &a, SLOT(quit())); // changed the
//variable name 'app' to 'a'

// Run the user-hook (doDownload) from the application event loop.
QTimer::singleShot(0, &d, SLOT(doDownload()));

return a.exec();
}

现在 Qt 将调用您的代码。无需显式退出应用程序,只需 emit finished() 即可正确清理所有内容。

如果这能解决您的问题,请告诉我。如果没有,可能还有其他鱼要炸。

关于qt - 关闭 QCoreApplication 的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29264782/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com