如何制作自己的自定义 QNetworkReply?
Posted
技术标签:
【中文标题】如何制作自己的自定义 QNetworkReply?【英文标题】:How do I make my own custom QNetworkReply? 【发布时间】:2018-02-01 18:54:43 【问题描述】:我一直在尝试创建自己的自定义 QNetworkReply 类,该类从回复中返回自定义字节。我确实从我也重载的 QNetworkAccessManager::createRequest() 重载中返回了该类。我的问题是,我的函数重载都没有被调用,因此 QWebView 的请求失败,因为回复是“损坏的”。我试图从 Qt 测试库的 FakeReply
中获得一些灵感,但我的工作失败了。
这是我的代码:
class FakeReply : public QNetworkReply
Q_OBJECT
public:
FakeReply(const QNetworkRequest& request, QByteArray &data, QObject* parent = 0);
~FakeReply();
QByteArray readAll();
QByteArray read(qint64 maxSize);
qint64 peek(char *buffer, qint64 maxlen);
QByteArray peek(qint64 maxLen);
qint64 size() const;
virtual qint64 bytesAvailable() const;
bool isFinished() const;
virtual void abort();
virtual void close();
bool isSequential() const;
protected:
qint64 readData(char*, qint64) override;
private:
QByteArray data;
;
还有 .cpp 文件:
FakeReply::FakeReply(const QNetworkRequest &request, QByteArray &bytes, QObject *parent)
: QNetworkReply(parent),
data(bytes)
setOperation(QNetworkAccessManager::GetOperation);
setRequest(request);
setUrl(request.url());
open(QIODevice::ReadOnly);
setFinished(true);
emit finished();
FakeReply::~FakeReply()
close();
QByteArray FakeReply::readAll()
qDebug() << "FakeReply::readAll() got called!";
size_t len = data.length();
const char *bytes = static_cast<const char*>(data.data());
char *buffer = static_cast<char*>(malloc(len));
ASSERT(buffer != NULL, "run out of memory");
memcpy(buffer, bytes, len);
QByteArray output;
output.setRawData(buffer, len);
data = data.remove(0, len);
return output;
QByteArray FakeReply::read(qint64 maxSize)
qDebug() << "QByteArray FakeReply::read() got called!";
static char* buffer = nullptr;
if(bytesAvailable() == 0)
return QByteArray();
size_t len = computeMaxNumberOfBytes(maxSize);
if(buffer != nullptr)
free(buffer);
buffer = static_cast<char*>(malloc(len));
ASSERT(buffer != NULL, "run out of memory");
memcpy(buffer, data.data(), len);
data = data.remove(0, len);
QByteArray output;
output.setRawData(buffer, len);
return output;
qint64 FakeReply::peek(char *buffer, qint64 maxlen)
qDebug() << "FakeReply::peek() got called!";
size_t len = computeMaxNumberOfBytes(maxlen);
memcpy(buffer, data.data(), len);
return static_cast<qint64>(len);
QByteArray FakeReply::peek(qint64 maxlen)
qDebug() << "FakeReply::peek(qint64 maxlen) got called!";
QByteArray output;
output.setRawData(data.data(), computeMaxNumberOfBytes(maxlen));
return output;
qint64 FakeReply::size() const
return data.length();
qint64 FakeReply::bytesAvailable() const
qDebug() << "FakeReply::bytesAvailable()";
return data.length();
bool FakeReply::isFinished() const
qDebug() << "FakeReply::isFinished() got called!";
return true;
void FakeReply::abort()
qDebug() << "FakeReply::abort() got called!";
void FakeReply::close()
qDebug() << "FakeReply::close() got called!";
bool FakeReply::isSequential() const
qDebug() << "FakeReply::isSequential() const got called!";
return false;
qint64 FakeReply::readData(char *, qint64)
qDebug() << "FakeReply::readData() got called!";
return 0;
类是这样使用的:
QNetworkReply *MyNetworkAccessManager::createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice *outgoingData)
QString path = request.url().path();
QNetworkReply *reply = QNetworkAccessManager::createRequest(op, request, outgoingData);
if(path == QStringLiteral("/testing"))
QByteArray response = waitThenReadAll(reply);
return new FakeReply(request, response);
return reply;
【问题讨论】:
所以你的 MyNetworkAccessManager::createRequest() 方法没有被调用?您可以为您的访问管理器发布 *.h 文件吗? 我的MyNetworkAccessManager::createRequest()
确实被调用了,但我的FakeReply
中的所有方法都不是由MyNetworkAccessManager::createRequest()
返回的。
【参考方案1】:
对于任何有同样问题的人,我从here
得到了一些代码示例的答案:我的代码中缺少的是我使用的是emit finish()
而不是
QTimer::singleShot(0, this, SIGNAL(readyRead()));
QTimer::singleShot(0, this, SIGNAL(finished()));
确实有效。
【讨论】:
好的,我确实看到了问题。你让它工作。那挺好的。您的问题是您在构造函数中调用了emit finished()
。信号在那里不起作用,因为该对象实际上还不存在(即:对new FakeReply(...)
的调用尚未返回),因此没有任何连接。但这是一个很好的解决方法。以上是关于如何制作自己的自定义 QNetworkReply?的主要内容,如果未能解决你的问题,请参考以下文章
如何设计制作JavaWeb项目的自定义桌面实现,求源码?新手谢谢!
无论如何要为Android中的来电和去电制作我的自定义用户界面吗?