PDA

View Full Version : QPixmap - object disappears after fetched from http



djuvsland
25th January 2010, 23:06
I have a problem on a project im working on. What I want to do is fetching a image from a folder on a web server, and store them as a QPixmap object. Everything goes fine, and the image can be set inside the function which loads the data from the bytearray. But the QPixmap object as defined in the header file, won't hold the data for later use.

Header file:


#ifndef HTTPBILDE_H
#define HTTPBILDE_H

#include <QBuffer>
#include <QHttp>
#include <QUrl>
#include <QPixmap>
#include <QPushButton>

class HttpBilde : public QObject {
Q_OBJECT

public:
HttpBilde(QString adresse);
~HttpBilde();

public slots:
void finished(int requestId, bool error);

signals:
void getPixmap(QPixmap);

private:
QBuffer *buffer;
QByteArray bytes;
QHttp *http;
int Request;
QUrl url;
QPixmap img;
};


Cpp file:


}// constructor
...
url.setUrl(adresse);
http = new QHttp(this);
buffer = new QBuffer(&bytes);

buffer->open(QIODevice::WriteOnly);
http->setHost(url.host());
Request=http->get(url.path(),buffer);

connect(http, SIGNAL(requestFinished(int, bool)),this, SLOT(finished(int, bool)));
}

}

void HttpBilde::finished(int requestId, bool error) {
if (Request==requestId){
img.loadFromData(bytes);
// here I can do whatever i like with the QPixmap (img) and i get correct image data
}
}

QPixmap HttpBilde::getPixmap() {
return img;
// The returned QPixmap gets size -1,-1 no pixmap data
}


If i send a signal from void HttpBilde::finished(int requestId, bool error) to a slot in another class, the correct pixmap data is sent. And I can set the pixmap to for example a QLabel. But i encounter the same problem in the other class if I try to store it in a QPixmap object in that class.

I have also tried deep copy with no luck. It holds the data as long as it gets emited trough signals but disappears afterwards.

high_flyer
26th January 2010, 09:40
The first things that I see before thinking about it is that you don't have a deceleration for the getPixmap() method.
It is bad practice to call signals and slots/methods with the same names!

djuvsland
26th January 2010, 09:49
It seems that when I put the header file on this forum I did som editing and it should be under "public" not "signals". I had rewritten the class to send out the pixmap from a signal, I will fix the original post.

update: the option edit post was not available on the first post, but the function getPixmap should be under "public" in the header file

high_flyer
26th January 2010, 10:25
But its not only the fact that it was under 'signals' - the signature is not the same!
void getPixmap(QPixmap);

and

QPixmap HttpBilde::getPixmap()

Are two different methods!

djuvsland
26th January 2010, 10:44
Yes sorry about that, but it was QPixmap getPixmap(); in the header file. What I do not understand is when I get the pixmap from a signal into a slot in another class it seems to be valid, and I can place it as an icon for a pushbutton or a label. But if I copy the data from the pixmap to a QPixmap private member object, it only holds the data as long as the slot reaches the end, and then the data disappears. I have checked even after doing a deep copy of the pixmap recieved that the data is valid and can be used, but it seems that after it stops at a function/slot end, it gets erased.

high_flyer
26th January 2010, 11:53
Just copy paste your code here, so we can help you.
It sounds like you have a problem of a local scope variable, maybe due to naming or typo errors.

djuvsland
26th January 2010, 13:20
No need to paste the code, I just found the solution.

This code in an external class:



HttpBilde *test = new HttpBilde("http://somepictureurl");
pixmap = test->getPixmap();
qDebug() << pixmap.size();


Gets size -1,-1. Because the getPixmap() function returns the QPixmap before http has completed loading the image from the web. Got it to work with a pushbutton and connected it to a slot which ran the pixmap = test->getPixmap(); afterwards.