maxwellhertz
maxwellhertz

Reputation: 483

How to scale a graphics taking the center of window as origin?

QPainter::scale takes the top-left corner of the window as an origin. In order to use the center of the window as an origin, I thought I could first translate the origin of the coordinate system to the center of the window using QPainter::translate and then scale the graphics:

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = nullptr) :
        QMainWindow(parent) {
        resize(600, 400);
    }

protected:
    void paintEvent(QPaintEvent *) override {
        QPainter painter(this);
        // draw a rectangle
        QRectF rectangle(10.0, 20.0, 80.0, 60.0);
        painter.drawRect(rectangle);

        // translate the origin of coordinate system to the center of window
        QPointF offset = rect().center();
        painter.translate(offset);

        // scale the rectangle
        painter.scale(2,2);
        painter.drawRect(rectangle);
    }
};

The example produces the following result:

Window with rectangles

The problem is that the scale is still made with regard to the top-left corner.

How to fix that?


Following is my solution.

QPainter painter(this);
// draw a rectangle
QRectF rectangle1(10.0, 20.0, 80.0, 60.0);
painter.drawRect(rectangle1);

// scale the rectangle by 2 times
QRectF rectangle2(10.0, 20.0, 80.0 * 2, 60.0 * 2);
// move it to the center of window
QPointF offset = rect().center() - rectangle2.center();
painter.translate(offset);
painter.drawRect(rectangle2);

And I get what I want like this: enter image description here

Upvotes: 0

Views: 786

Answers (2)

eyllanesc
eyllanesc

Reputation: 244093

Finding the appropriate transformation that should be applied to QPainter is not a simple task since it involves centering one element on another, moving it, etc. The simplest thing is to transform the rectangle as shown below:

void Widget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    // draw a rectangle
    QRectF rectangle(10.0, 20.0, 80.0, 60.0);
    painter.drawRect(rectangle);
    // scale
    rectangle.setSize(2*rectangle.size());
    // translate
    rectangle.moveCenter(rect().center());
    painter.drawRect(rectangle);
}

Upvotes: 1

scopchanov
scopchanov

Reputation: 8419

You miss one step, i.e. to re-translate the painter back after the scale. In other words, between

painter.scale(2,2);
painter.drawRect(rectangle);

add

painter.translate(-offset);

Upvotes: 1

Related Questions