[Solved] QNetworkAccessManager
-
The get and post methods of QNAM are not virtual. Perhaps that is what you are experiencing? Instead of reimplementing these operations, you should reimplement the protected virtual createRequest method. This method is called by the get, post and put methods.
-
Hi,
Thanks for the replies. Yes the problem is get and post are not virtual but i don't think createRequest will work for me because i want to load some resources from a web page directly myself and let others go thru the default path. Like stylesheets etc.
Im assuming it can't be done without having virtual get and put functions.Cheers Simon
-
It can be done as long as you assure that the non-virtual replaced methods are not called through a base class pointer.
But why shoudn't QNetworkAccessManager::createRequest() be sufficient in your case? Just manipulate the QNetworkRequest and pass it up the the base class.
@
class NetworkAccessManager : public QNetworkAccessManager
{
protected:
QNetworkReply* createRequest(Operation op, const QNetworkRequest& req, QIODevice* outgoingData = 0)
{
QNetworkRequest request(req);if(request.url().path() == "styles/style.css") { QUrl url(request.url()); url.setPath("anotherStyle/style.css"); request.setUrl(url); } return QNetworkAccessManager::createRequest(op, request, outgoingData); }
};
@
Brain to terminal. Not tested. -
Hi,
Yea the problem is i don't want to fetch the resource via a url hence passing the QNetworkRequest up to the base class will probably break the base class also i might have to do some extra processing on the resource before returning the http response to the browser.
As far as i can tell the only way i can do this is to override the get/post functions etc.
Im would not have to call the non-virtual methods through a bas class pointer, but i dont really understand how this could be done ??Thanks for your response.
-
Well, get() and alike just call createRequest(), so by replacing get() instead of createRequest() you haven't won anything. There is no need to call the base class createRequest() implementation. Just wrap your resource in a QNetworkReply and make sure it emits the finished signal.
@
class NetworkAccessManager : public QNetworkAccessManager
{
protected:
QNetworkReply* createRequest(Operation op, const QNetworkRequest& req, QIODevice* outgoingData = 0)
{
if(request.url().path() == "styles/style.css")
{
QNetworkReply* reply = createReplyForResource("anotherStyle/style.css");
reply->emitFinishedSignal();return reply; } else { return QNetworkAccessManager::createRequest(op, request, outgoingData); } }
};
@
As to your second question: You can replace a non-virtual method, but you cannot have polymorphism doing so. A small example:
@
class BaseClass
{
public:
void printType() { qDebug() << "BaseClass"; }
virtual void printTypeVirtual() { qDebug() << "BaseClass"; }
};class DerivedClass : public BaseClass
{
public:
void printType() { qDebug() << "DerivedClass"; }
virtual void printTypeVirtual() { qDebug() << "DerivedClass"; }
};BaseClass* baseClass = new BaseClass;
baseClass->printType(); // "BaseClass"
baseClass->printTypeVirtual(); // "BaseClass"DerivedClass* derivedClass = new DerivedClass;
derivedClass->printType(); // "DerivedClass"
derivedClass->printTypeVirtual(); // "DerivedClass"baseClass = derivedClass;
baseClass->printType(); // "BaseClass", not "DerivedClass" as printType()
// is not virtual and thus does not support polymorphism
baseClass->printTypeVirtual(); // "DerivedClass", as expected
@This means, if someone calls your replaced get() method through a NetworkAccessManager pointer the replaced implementation will be used, but if someone calls your replaced get() method through a QNetworkAccessManager pointer the original implementation will be used. See "here":http://www.parashift.com/c++-faq-lite/virtual-functions.html#faq-20.3.