Как масштабировать графику, используя центр окна как источник? - PullRequest
0 голосов
/ 14 октября 2018

QPainter::scale принимает верхний левый угол окна в качестве источника.Чтобы использовать центр окна в качестве источника, я подумал, что сначала можно перевести начало координат системы координат в центр окна, используя QPainter::translate, а затем масштабировать графику:

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);
    }
};

В примере получен следующий результат:

Window with rectangles

Проблема заключается в том, что шкала все еще выполняется относительно верхнего левого угла.

Как это исправить?


Вот мое решение.

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);

И я получаю то, что хочу, вот так: enter image description here

Ответы [ 2 ]

0 голосов
/ 15 октября 2018

Найти подходящее преобразование, которое должно быть применено к QPainter, - непростая задача, поскольку оно включает центрирование одного элемента на другом, его перемещение и т. Д. Самое простое - преобразовать прямоугольник, как показано ниже:

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);
}
0 голосов
/ 15 октября 2018

Вы пропускаете один шаг, то есть повторно переводите художника обратно за шкалу.Другими словами, между

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

добавить

painter.translate(-offset);
...