Используйте окно/окно просмотра для переключения Q-оси оси Y
Я использую Qt 4.7 QPainter для рисования нескольких полигонов и т.д. в виджет. Я надеюсь изменить систему координат так, что (0,0) находится в центре моего виджета, а ось x/y ведет себя стандартным "декартовым" способом (т.е. 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-документов и Интернета я не могу понять это!
Спасибо,
Крис
Ответы
Ответ 1
Использовать класс QMatrix
. Он задает двумерные преобразования. QMatrix
установлено значение QPainter
.
Но помните, в вашем случае, если вы конвертируете ваши виджеты в декартовы коорды, вам нужно будет поставить первую точку в (- 10, -10) (не в (- 10,10), как вы уже упоминали), чтобы нарисовать прямоугольник с центром в (0,0), поскольку ось Y теперь растет, а X-Axis теперь растет правильно.
Все, что вам нужно, это преобразовать вашу систему координат следующим образом:
Вот код, набранный функцией 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]()
обновление apr 07, 2014
Этот вопрос задавали давно, и с тех пор многое изменилось. Для тех, кто задает себе тот же вопрос сегодня (начало 2014 года), мой личный ответ заключается в том, что с Qt 4.3 можно легче решить проблему с переводом текста.
Вы правы. Текст также обрабатывается, потому что он рисуется с тем же живописцем. Вы можете нарисовать текст в конце, когда все перевернутые рисунки сделаны, если это возможно. Этот метод не является удобным из-за новых расчетов положения текста. Также вам нужно отбросить настройки для живописца.
Теперь я бы рекомендовал вам использовать QGraphicsView
из-за огромной поддержки 2D-графики. Также для каждого флага QGraphicsItem
ItemIgnoresTransformations
можно установить флаг, который позволяет игнорировать унаследованные преобразования (т.е. Его позиция по-прежнему привязана к его родительскому элементу, но игнорирование ротации или просмотра, масштабирование или сдвиговые преобразования игнорируются). Этот флаг полезен для сохранения элементов текстовой метки в горизонтальном и немасштабированном виде, поэтому они будут по-прежнему доступны для чтения, если графическое представление будет преобразовано
Ответ 2
В приведенном выше ответе также будет отображаться текст, "p" будет "b". Чтобы избежать этого, перед тем, как текст будет нарисован, вам нужно отбросить ось y, и вы должны изменить знак на y-coord для текстовой позиции при ее рисовании. Я думаю, это немного уродливо, или есть лучший способ?
Ответ 3
Как указано выше, текст чертежа также отображается с ног на голову. Это простое решение, см. Ниже. Мы временно отключим преобразование мира для рисования текста. Обратите внимание, что текст больше не масштабируется.
в вашем графическом коде мы хотим нарисовать текст по координате 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);