QT. Strange problem drawing images and rectangles with QPainter.

Started by
5 comments, last by Dospro 9 years, 8 months ago

Hi. I have a little issue with QImage and QPainter. Let me explain myself.

I have a mainWindow application. Inside i have some layouts. Inside of one of the i placed a costum Widget.

This custom Widget inherited from QWidget. The purpose of this widget is to display an image. The image is loaded from a file.
Until here, everything works perfectly.

After loading the image, some analysis is made to that image. This analysis gives me some QRects.

In the painEvent method of my custom widget i use Qpainter to first draw the image and then draw the rects.

The problem is that the rects are drawn larger then they should be.
[sharedmedia=core:attachments:23169]

In this image i show a little example. The white rectangle should be the same size as the green square.
The image a 50x50 pixels. The QRect has the correct x, y, width and height. But still, it draw a bigger rectangle.

Does anyone know that's going on?
Here is the paintEvent code:


painter->begin(this);
painter->drawImage(QPoint(0, 0), *spriteImage);
painter->setPen(Qt::white);

foreach(QRect r, spriteCoords) {
     painter->drawRect(r);
}
painter->end();
Advertisement

The first step to debugging this, is changing the code to:


painter->begin(this);
painter->drawImage(QPoint(0, 0), *spriteImage);
painter->setPen(Qt::white);

//----TEMP----
painter->drawRect(19,19,15,15);
//------------

/*foreach(QRect r, spriteCoords) {
     painter->drawRect(r);
}*/

painter->end();

By manually passing in coordinates, you can figure out easily if QPainter is the problem, or if your spriteCoords have the wrong values. What values does the QRect contain? Use qDebug() to print it out right before drawing it, so you can be certain. You can use the debugger also, but if you're on Windows running MinGW's GDB, it's not the best debugger in the world. sad.png (Maybe later versions have improved though - I'm currently on last year's MinGW and Qt releases)

Also, where are you getting your QPainter from, and what function is this being called in? Could you post the entire function? If it was handed to you, and you didn't create it yourself, maybe QPainter::scale() was called elsewhere?

Hi. Thanks for your answer.

I have tried the manually set coords. The result is the same.

I have never use qDebug() unsure.png .

I developing this in Linux and i use printf messages for tracing values. Sometimes i use gdb. But it 's not that practical in this situations.

In the simple example i showed the rect has coords (18, 19, 33, 33). Those are the correct coords for the green square.

I create my own QPainter in the Widget class constructor.


cSpriteViewer::cSpriteViewer() {
    spriteImage = NULL;
    painter = new QPainter(this);
}

void cSpriteViewer::paintEvent(QPaintEvent*) {
    if (spriteImage) {

        painter->begin(this);
        painter->drawImage(QPoint(0, 0), *spriteImage);
        painter->setPen(Qt::white);
        //painter->setBrush(Qt::NoBrush);

        //foreach(QRect r, spriteCoords) {
            //printf("Drawing at (%d %d) (%d %d)\n", r.x(), r.y(), r.width(), r.height());
        //    painter->drawRect(r.x(), r.y(), r.width(), r.height());
        //}
        //painter->drawRect(spriteCoords[0]);
        painter->drawRect(18, 19, 33, 33);
        painter->end();
    }
}

That's what i have now.

I've been reading QT documentation but i can't find anything related to this.

Ah, then you're likely mixing up (x,y,w,h) with (x1,y1,x2,y2) rectangles.

Some rectangles are formed by a point and the width and height, others are formed by the start point and the end point.

The green rectangle starts at (18,19) and ends at (33,33), but when you call:


painter->drawRect(18, 19, 33, 33);

You're actually saying you want a rectangle 33 pixels wide and 33 pixels high [QPainter::drawRect()]. So the problem is likely that when you set spriteCoords, you are using the wrong values.

If you want to create a rect using the beginning and end points, you do:


QRect myRect(QPoint(x1,y1), QPoint(x2,y2));

If you want to create a rect using x,y,w,h, you do:


QRect myRect(x,y,w,h);

There's different constructors.

Also, you can pass a QVector<QRect> to QPainter::drawRects() (drawRects with an 's' at the end). You don't have to foreach() over the vector, if it's a QVector<QRect>.

Wow. That solved it for the manual coords.

Now, one more doubt.

When i use drawRect(QRect) i still get the bad results. Should i use some other drawRect method?

I edited my previous post, but the issue is how you construct your 'spriteCoords'.

Jajajaja. That was dumb(my previous post). The problem was with QRect, no QPainter.drawRect.

Solved.

Thank you very much.

This topic is closed to new replies.

Advertisement