QGraphicsView и QGraphicsItem:не масштабируйте элемент при масштабировании прямоугольника вида
-
10-07-2019 - |
Вопрос
Я использую Qts QGraphicsView
- и QGraphicsItem
-подклассы.есть ли способ не масштабировать графическое представление элемента в представлении при изменении прямоугольника представления, напримерпри увеличении масштаба.Поведение по умолчанию заключается в том, что мои элементы масштабируются по отношению к моему прямоугольнику просмотра.
Я хотел бы визуализировать 2d-точки, которые должны быть представлены тонким прямоугольником, который не должен масштабироваться при масштабировании вида.Смотрите типичное программное обеспечение для 3d-моделирования для справки, где точки вершин всегда отображаются в одном и том же размере.
Спасибо!
Решение
Установите QGraphicItem
флаг страны QGraphicsItem::ItemIgnoresTransformations
значение true у вас не работает?
Другие советы
Я столкнулся с такой же проблемой, и мне потребовалось некоторое время, чтобы разобраться в ней.Вот как я решил эту проблему.
Расширьте класс QGraphicsItem, переопределите paint().Внутри paint() сбросьте коэффициент масштабирования преобразования на 1 (это m11 и m22) и сохраните m11 (коэффициент масштабирования x) и m22 (коэффициент масштабирования y) перед сбросом.Затем рисуйте, как обычно, но умножьте x на m11, а y на m22.Это позволяет избежать рисования с преобразованием по умолчанию, но явно вычисляет позиции в соответствии с преобразованием сцены.
void MyItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *item, QWidget *widget)
{
QTransform t = painter->transform();
qreal m11 = t.m11(), m22 = t.m22();
painter->save(); // save painter state
painter->setTransform(QTransform(m11, t.m12(), t.m13(),
t.m21(), 1, t.m23(), t.m31(),
t.m32(), t.m33()));
int x = 0, y = 0; // item's coordinates
painter->drawText(x*m11, y*m22, "Text"); // the text itself will not be scaled, but when the scene is transformed, this text will still anchor correctly
painter->restore(); // restore painter state
}
Следующий блок кода рисуется с преобразованием по умолчанию
void MyItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *item, QWidget *widget)
{
int x = 0, y = 0;
painter->drawText(x, y, "Text");
}
Вы можете попробовать и то, и другое, чтобы увидеть разницу.Надеюсь, это поможет.
Как насчет этого:
#include <QtGui/QApplication>
#include <QtGui/QGraphicsScene>
#include <QtGui/QGraphicsView>
#include <QtGui/QGraphicsRectItem>
int main(int argc, char* argv[]) {
QApplication app(argc, argv);
QGraphicsScene scene;
scene.addText("Hello, world!");
QRect rect(50, 50, 100, 100);
QGraphicsRectItem* recti = scene.addRect(rect);
QGraphicsView view(&scene);
// Set scale for the view
view.scale(10.0, 5.0);
// Set the inverse transformation for the item
recti->setTransform(view.transform().inverted());
view.show();
return app.exec();
}
Как вы можете видеть, текст увеличен, а прямоугольник - нет.Обратите внимание, что это предотвращает не только масштабирование прямоугольника, но и другие преобразования.
Я обнаружил, что если я создам новый класс и переопределю функцию paint, я могу сделать
void MyDerivedQGraphicsItem::paint(QPainter *painter,
const QStyleOptionGraphicsItem *option,
QWidget *widget)
{
double scaleValue = scale();
double scaleX = painter->transform().m11();
setScale(scaleValue / scaleX);
QGraphicsSvgItem::paint(painter,option,widget);
}
Это лучший способ сделать это, который я нашел на данный момент, но я все еще возюсь.
Следующее решение отлично сработало для меня:
void MyDerivedQGraphicsItem::paint(QPainter *painter, const StyleOptionGraphicsItem *option, QWidget *widget)
{
double scaleValue = scale()/painter->transform().m11();
painter->save();
painter->scale(scaleValue, scaleValue);
painter->drawText(...);
painter->restore();
...
}
Мы также можем умножить значение scaleValue на другие значения, которые мы хотим сохранить постоянными вне среды сохранения / восстановления.
QPointF ref(500, 500);
QPointF vector = scaleValue * QPointF(100, 100);
painter->drawLine(ref+vector, ref-vector);