【问题标题】:Qt5 QNetworkAccessManager finished signal never emitsQt5 QNetworkAccessManager 完成信号永远不会发出
【发布时间】:2015-04-03 10:50:18
【问题描述】:

我有一个非常令人困惑的问题。

我有一个从一些 ftp 服务器下载文件的简单项目。效果很好。

然后,我尝试将相同的代码实现到一个更大的项目中(第一个是控制台应用程序,第二个是 GUI,但我认为这不会改变任何东西..)。

在做了一些调试之后,在我看来,来自QNetworkAccessManagerfinished() 信号以某种方式永远不会被发出(或接收)。 同样,完全相同的代码行作为一个单独的项目工作。

下载器.h

#ifndef DOWNLOADER_H
#define DOWNLOADER_H

#include <QObject>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QUrl>
#include <QFile>
#include <QDebug>

class Downloader : public QObject
{
    Q_OBJECT

public:
    explicit Downloader(QObject *parent = 0);



signals:

    void dloadend();
    void printed();

public slots:
    void replyFinished (QNetworkReply *reply);
    void doDownload(QUrl url);
    void printDLend();

private:
    QNetworkAccessManager *manager;
};

#endif // DOWNLOADER_H

下载器.cpp

#include "downloader.h"

Downloader::Downloader(QObject *parent) :
    QObject(parent)
{
}
void Downloader::doDownload(QUrl url)
{
    qDebug()<<"entry: doDownload\n";
    QNetworkRequest req(url);
    manager = new QNetworkAccessManager(this);
    connect(manager, SIGNAL(finished(QNetworkReply*)),this,SLOT(printDLend()));//SLOT(replyFinished(QNetworkReply*)));
    manager -> get(req);
    qDebug()<<"exit: doDownload\n";
}

void Downloader::replyFinished (QNetworkReply *reply)
{
    qDebug()<<"entry: reply\n";

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

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

        QFile *file = new QFile("C:/users/jelicicm/Desktop/test1.hex");

        if(file->open(QFile::Append))
        {
            file->write(reply->readAll());
            file->flush(); file->close();
            qDebug() <<"Downloaded file size:" <<file->size() <<"Bytes";
            qDebug() <<"File name: "<< file->fileName();
;
        }
        delete file;
    }

    reply->deleteLater();
    manager->deleteLater();
    emit dloadend();

}

mainwindow.cpp(重要部分)

void MainWindow::on_actionDownloadFirmwareImage_triggered()
{
    Downloader d;

    QUrl url("ftp://ftp.xenbase.org/pub/Genomics/JGI/Xenla6.0/Xenla_6.0_JGI_Gene_Models.fasta.tgz");

    qDebug() << "url, debug";
    ui->plainTextEdit->appendPlainText(url.toDisplayString());

    d.doDownload(url);

    QObject::connect(&d,SIGNAL(dloadend()),this, SLOT(printDLend()));
}

无法理解这一点。

欢迎任何帮助,

谢谢!

编辑> 更多信息: 调试器发布此消息>

网址,调试

条目:下载

退出:下载

【问题讨论】:

    标签: qt5 signals-slots qnetworkaccessmanager qnetworkrequest qnetworkreply


    【解决方案1】:

    您在堆栈上创建对象Downloader,并在您的函数退出后立即将其删除。您必须使用new 创建对象,并提供MainWindow 对象作为父对象,因此关闭主窗口后,该对象将被销毁。 如果下载完成,你仍然需要销毁对象,所以只需将dloadend()信号连接到deleteLater()插槽,Qt循环将在处理完所有信号后立即删除你的对象。

    void MainWindow::on_actionDownloadFirmwareImage_triggered()
    {
        Downloader *d = new Downloader(this);
    
        QUrl url("ftp://example.com/some.file.tgz");
    
        qDebug() << "url, debug";
        ui->plainTextEdit->appendPlainText(url.toDisplayString());
    
        d->doDownload(url);
    
        QObject::connect(d,SIGNAL(dloadend()),this, SLOT(printDLend()));
        QObject::connect(d,SIGNAL(dloadend()), d, SLOT(deleteLater()));
    }
    

    【讨论】:

    • 你是对的。我完全没有想到。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-08
    • 1970-01-01
    • 1970-01-01
    • 2011-02-16
    • 1970-01-01
    • 2023-03-31
    相关资源
    最近更新 更多