PDA

View Full Version : QPainter ouside of paintEvent with a pixmap



bitChanger
21st March 2006, 20:29
I'm porting a Qt 3.3.2 application to Qt 4.1.1

In Qt 3 you can create a QPainter p(&pixmap) and paint to the pixmap anywhere in the code.

In Qt 4 it says that all painting must take place inside the paintEvent.

Why is that the following will work in Qt 4 outside of paintEvent



void someFunc()
{
Pixmap pix(size());
pix.fill(this, 0, 0);
QPainter p(&pix); // no error
// paint away
}


but, the following will not.



// here ptrPix was filled by another function
void someFunc()
{
QPainter p(ptrPix); // QPainter::begin(), paintdevice returned engine == 0, type: 2
// paint away
}


am i missing a concept here?

I will move all of my painting to the paintEvent so that I can take advantage of the double buffering built in to Qt 4, I just want to know what is going on with the above statements.

Thanks.

jacek
21st March 2006, 20:58
From Qt docs:
Unless a widget has the Qt::WA_PaintOutsidePaintEvent attribute set. A QPainter can only be used on a widget inside a paintEvent() or a function called by a paintEvent().
This is about painting on a widget, not on a pixmap.

bitChanger
21st March 2006, 21:11
The first example creates a QPixmap of the widgets size and fills it with the widgets background color or pixmap. Then you can paint on the pixmap with that QPainter.

The second one assigns a prefilled pixmap pointer to a QPainter and then paints on the pixmap.

They seem to be doing the same thing, which neither is painting to a widget.

So, I'm still confused why one would work and one would not.

Please explain more if I'm missing a point.

jacek
21st March 2006, 21:59
Do you use threads?

bitChanger
22nd March 2006, 04:50
Yes 5 of them in this application.

jacek
22nd March 2006, 10:25
Do you modify QPixmaps in non-GUI thread? If yes, then you will have to switch to QImages.

bitChanger
22nd March 2006, 16:39
After trying some more things I'm confused as to why the following don't work in Qt 4.1.1
This is an application not using threads.



void MyType::paintEvent(QPaintEvent*)
{
QPainter painter;
someFunc(&painter);

painter.begin(this);
painter.drawPixmap(QPoint(0, 0), *pmap);
painter.end();
}

void MyType::someFunc(QPainter *painter)
{
painter->begin(pmap);
painter->setPen(dark);
painter->drawLine(0, 0, 50, 50);
// .. do something useful
painter->end();
}

jacek
22nd March 2006, 16:54
How do you create that pmap pixmap?

bitChanger
22nd March 2006, 17:11
class MyType : public QWidget
{
public:
// ... methods

private:
QPixmap* pmap;
QImage* image;
QColor* backgroundColor;
};

void MyType::createImage()
{
image = new QImage(50, 50, QImage::Format_RGB32);
image->fill(backgroundColor->rgb());

for (int i=0; i<50; i++)
{
QRgb rgb = qRgb(i, i+25, i+50);
for (int x=0; x<50; ++x)
image->setPixel(x, i, rgb);
}

convertImage();
}

void MyType::convertImage()
{
pmap = new QPixmap();
pmap->fromImage(*image, Qt::PreferDither);
update();
}


Hope this is enough sudo code for you. ;)

jacek
22nd March 2006, 17:23
QPixmap::fromImage() is static.

It should be something like:
void MyType::convertImage()
{
pmap = new QPixmap( QPixmap::fromImage(*image, Qt::PreferDither) );
update();
}

bitChanger
22nd March 2006, 19:45
Good catch, now it makes sense. Since static member functions have no "this" pointer my usage was wrong. That fixed it.

Thanks again.