首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >图像下载器类

图像下载器类
EN

Code Review用户
提问于 2016-03-23 22:41:46
回答 1查看 293关注 0票数 3

我在C++和Qt方面都是新手。这个类在我的项目中用于从web服务获取图像。

如果在前面的调用完成之前对StartDownload进行了新的调用,那么可以安全地丢弃旧的调用,因为不再需要它了。这是因为对每个调整大小事件提出了新的请求,因为服务的参数之一是图像大小(图像中的字体大小与图像大小相适应)。

因此,当请求被取消时,Qt会打印一个错误消息:QCoreApplication::postEvent: Unexpected null receiver。这不会干扰任何功能,但告诉我我没有正确地处理取消请求的问题。这些消息中有几条是在我调整窗口大小和调用CancelDownload时打印出来的。

除此之外,任何关于我的设计或C++成语的一般反馈都是受欢迎的!

注意:我使用的是C++11和QT5.6。

报头

代码语言:javascript
复制
#ifndef DOWNLOADER_H
#define DOWNLOADER_H

#include <QtNetwork/qnetworkaccessmanager.h>
#include <qbytearray.h>
#include <QObject>

class Downloader: public QObject
{
    Q_OBJECT

public:
    Downloader();
    ~Downloader();
    void StartDownload(QUrl url);

private:
    void CancelDownload();

    QNetworkAccessManager mNetworkAccessManager;
    QNetworkReply *mCurrentReply;

signals:
    void DownloadFinished(QByteArray bytes);

private slots:
    void HandleFinishedDownload();
};

#endif // DOWNLOADER_H

代码语言:javascript
复制
#include <QtNetwork/qnetworkrequest.h>
#include <QtNetwork/qnetworkreply.h>
#include "Downloader.h"

Downloader::Downloader()
    : mNetworkAccessManager(), mCurrentReply(Q_NULLPTR)
{
}

Downloader::~Downloader()
{
    CancelDownload();
    mNetworkAccessManager.deleteLater();
}

void Downloader::CancelDownload()
{
    if (mCurrentReply != Q_NULLPTR) {
        mCurrentReply->abort();
        mCurrentReply->deleteLater();
        mCurrentReply = Q_NULLPTR;
    }
}

void Downloader::StartDownload(QUrl url)
{
    CancelDownload();

    QNetworkRequest request(url);
    mCurrentReply = mNetworkAccessManager.get(request);
    connect(mCurrentReply, &QNetworkReply::finished, this, &Downloader::HandleFinishedDownload);
}

void Downloader::HandleFinishedDownload()
{
    if (!mCurrentReply) {
        qCritical("Null reply in HandleFinishedDownload");
        return;
    }

    if (mCurrentReply->error() == QNetworkReply::NoError) {
        emit DownloadFinished(mCurrentReply->readAll());
    }
    else if (mCurrentReply->error() != QNetworkReply::OperationCanceledError) {
        qWarning() << "Failed download:" << mCurrentReply->errorString();
    }

    mCurrentReply->deleteLater();
    mCurrentReply = Q_NULLPTR;
}

更新

虽然我在一个自我回答中解决了上述问题,但我仍然在寻找一个全面的回顾!

EN

回答 1

Code Review用户

发布于 2016-03-29 21:12:56

错误信息是由于我误解了deleteLater的目的而造成的。正如文献资料所暗示的,只有在删除槽内的对象(如HandleFinishedDownload )时,成员函数才是必需的。

注意:不要删除连接到error()或finished()信号的槽中的对象。使用deleteLater()。

在所有其他情况下,应该使用标准的delete关键字。因此,这里是CancelDownload的更新实现。

代码语言:javascript
复制
void Downloader::CancelDownload()
{
    if (mCurrentReply != Q_NULLPTR) {
        mCurrentReply->abort();
        delete mCurrentReply; // this is the only altered line
        mCurrentReply = Q_NULLPTR;
    }
}
票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/123709

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档