Используйте окно / окно просмотра, чтобы перевернуть QPainter по оси Y - PullRequest
11 голосов
/ 11 декабря 2010

Я использую Qt 4.7 QPainter для рисования некоторых полигонов и т. Д. В виджет.Я надеюсь изменить систему координат так, чтобы (0,0) находился в центре моего виджета, а ось x / y велась стандартным «декартовым» образом (т. Е. У увеличивалось при движении вверх и уменьшалось при движении)вниз").Другими словами, я хочу, чтобы координаты были «математическими», а не «компьютерными», если вы понимаете, о чем я.: -)

Я пытаюсь сделать это, используя setViewport () и setWindow (), а не делать математику самостоятельно, так как было бы неплохо иметь возможность просто вызывать методы рисования напрямую с моими координатами.

Вот что у меня так далеко:

// Setup coordinates
double screenWidth = width();
double screenHeight = height();

double windowWidth = 100.0;
double windowHeight = (screenHeight / screenWidth) * windowWidth;

painter.setViewport(0, 0, screenWidth, screenHeight);
painter.setWindow(-(windowWidth / 2.0), -(windowHeight / 2.0), windowWidth, windowHeight);

// Draw stuff
painter.setPen(Qt::NoPen);
painter.setBrush(Qt::blue);
painter.drawRect(-10, -10, 20, 20);

Теперь это работает просто отлично, в том, что рисует красивый синий квадрат в середине экрана.Проблема в том, что я должен сказать, что верхний левый угол (-10, -10).Я хотел бы иметь возможность сделать это (-10, 10), так как это то, что было бы в декартовых координатах.

Я попытался возиться с setWindow / setViewport, чтобы получить этот "поворот оси Y", но безрезультатно.Это кажется очень простым и простым делом, но после изучения документов Qt и Интернета я не могу этого понять!

Спасибо,
Крис

Ответы [ 4 ]

23 голосов
/ 11 декабря 2010

Используйте класс QMatrix. Он определяет 2D-преобразования. QMatrix установлено на QPainter.

Но помните, что в вашем случае, если вы преобразуете координаты вашего виджета в декартовы координаты , вам придется поставить первую точку на (- 10, -10) (не в (- 10,10) , как вы упомянули) , чтобы нарисовать прямоугольник с центром в (0,0) , потому что ось Y теперь растет вверх и ось X теперь растет вправо .

Все, что вам нужно, это преобразовать вашу систему координат следующим образом:

  • перевод происхождение с (0,0) до середины виджета:
    alt text

  • масштаб ось Y на -1 коэффициент:
    alt text

Вот код, набранный в paintEvent() функции виджета:

QPainter pn( this );

int w_2 = width() / 2;
int h_2 = height() / 2;

{ // X- and Y-Axis drawing
    pn.setPen( Qt::blue );
    pn.drawLine( 0, h_2, width(), h_2);     // X-Axis
    pn.drawLine( w_2, 0 , w_2, height() );  // Y-Axis
}

QMatrix m;
m.translate( w_2, h_2 );
m.scale( 1, -1 );

pn.setMatrix( m );
pn.setPen( Qt::NoPen );
pn.setBrush( QBrush( Qt::blue, Qt::Dense4Pattern ) );
pn.drawRect( -10, -10, 20, 20 );
* * Результат тысяча сорок-девять:
alt text

обновление 7 апреля 2014 г.

Этот вопрос задавался очень давно, и с тех пор многое изменилось. Для тех, кто задает себе тот же вопрос сегодня (начало 2014 года), тогда мой личный ответ таков: с Qt 4.3 стало проще решать проблему с перелистыванием текста.

Вы правы. Текст также запечатывается, потому что он нарисован тем же художником. Вы можете нарисовать текст в конце, когда все перевернутые рисунки сделаны, если это возможно. Этот метод не удобен из-за новых расчетов положения текстов. Также вам нужно будет сбросить настройки для художника. Теперь я бы порекомендовал вам использовать QGraphicsView из-за огромной поддержки 2D-рисования. Также для каждого QGraphicsItem ItemIgnoresTransformations может быть установлен флаг, который позволяет ему игнорировать унаследованные преобразования (т. Е. Его позиция все еще привязана к его родительскому элементу, но преобразования вращения родительского элемента или представления, преобразования масштаба или сдвига игнорируются). Этот флаг полезен для хранения элементов текстовой метки в горизонтальном и немасштабированном виде, поэтому они по-прежнему будут доступны для чтения, если графическое представление преобразуется

3 голосов
/ 19 марта 2012

Приведенный выше ответ также перевернет текст, «p» будет «b».Чтобы избежать этого, вам нужно перевернуть ось y перед прорисовкой текста, а также изменить знак y-координаты для положения текста при его прорисовке.Это немного уродливо, я думаю, или есть лучший способ?

1 голос
/ 02 сентября 2015

Как указано выше, текст для рисования также отображается перевернутым. Существует простое решение, см. Ниже. Мы временно отключим трансформацию мира для рисования текста. Обратите внимание, что текст больше не масштабируется.

в вашем коде рисования мы хотим нарисовать текст по координате QPointF P;

Painter pn( this );

// calculate the point with the transform
QPointF p = pm.transform().map(P);

// Disable Transform temporary
pn.setWorldMatrixEnabled(false);

// draw it ordinary, no scaling etc
pn.drawText(p, QString("HI FRIENDS!"));

// Enable the transform again
pn.setWorldMatrixEnabled(true);
0 голосов
/ 03 апреля 2018

Мне нужно было перевернуть ось Y, чтобы рисовать линии и многоугольники, используя Qt из точек, определенных в координатах Java. Я полагаю, что другие должны будут делать это при переносе с Java на системы координат Qt. Обсуждение выше было полезно. Мое решение было:

painter.translate(0,height());
painter.scale(1.0, -1.0);

, а затем приступайте к рисованию линий и полигонов.

...