Перемещение QPixmap в угол QGraphicScene

#qt #qt4

#qt #qt4

Вопрос:

У меня есть QGraphicsView и QGraphicsScene, соединенные следующим образом:

 graphicsScene->setSceneRect(this->graphicsView->rect());
graphicsView->setScene(this->Scene);
  

Затем я загружаю изображение и добавляю его в сцену:

   QPixmap pixmap;
  pixmap.load(fileName);

  pixmap = pixmap.scaled(this->graphicsView->size());
  QGraphicsPixmapItem* item = this->Scene->addPixmap(pixmap);
  

Теперь, как описано в документации, угол изображения равен (0,0), что не является углом GraphicsScene. Я знаю, что могу расположить результирующее пиксельное изображение, выполнив:

 item->setPos(this->Scene->sceneRect().x(), this->Scene->sceneRect().y());
  

Однако, похоже, я не могу понять координаты прямоугольников сцены или представления. Кто-нибудь может объяснить, как я мог бы переместить пиксельную карту в угол сцены / представления?

Спасибо,

Дэвид

РЕДАКТИРОВАТЬ: вот полный конструктор формы. QGraphicsView был создан в Qt Designer и находится внутри GridLayout:

 Form::Form(QWidget *parent)
    : QWidget(parent)
{
  setupUi(this);

  QGraphicsScene* scene = new QGraphicsScene;
  scene->setSceneRect(this->graphicsView->rect());
  this->graphicsView->setScene(scene);

  QPixmap pixmap;
  pixmap.load("image.png");
  pixmap = pixmap.scaled(this->graphicsView->size());

  scene->addPixmap(pixmap);

}
  

Я также пробовал это:

   QGraphicsScene* scene = new QGraphicsScene;
  this->graphicsView->setScene(scene);

  QPixmap pixmap;
  pixmap.load("/home/doriad/glasses.jpg");

  QGraphicsPixmapItem * item = scene->addPixmap(pixmap);
  this->graphicsView->fitInView (item);
  

но изображение кажется крошечным, а не заполняет вид, как я ожидал. Кто-нибудь может это объяснить?

Полный проект и изображение доступны здесь: daviddoria.com/Uploads/qt/QPixmapPosition

Комментарии:

1. Вас интересует угол сцены или угол представления, независимо от того, где он может быть расположен?

2. Мне нужна только одна сцена в представлении, поэтому в идеале я хотел бы, чтобы угол сцены совпадал с углом представления — тогда угол пиксельной карты мог совпадать с любым, и это было бы то же самое.

Ответ №1:

Не беспокойтесь о масштабировании пиксельной карты самостоятельно или даже о ее переводе, пусть представление сделает это за вас.

Используйте graphicsView->fitInView(pixmap); , но вы должны прочитать документацию для :

Платформа представления графики Qt

void QGraphicsView::setSceneRect (QRectF )

void QGraphicsView::translate ( qreal dx, qreal dy )

void QGraphicsView::fitInView ( const QGraphicsItem * item, ... )

Взаимодействие QGraphicsScene и QGraphicsView заключается в том, что у вас может быть одна сцена с по крайней мере одним или несколькими видами.

Хорошим примером, о котором мне нравится думать, является увеличенный вид части карты с мини-видом всей карты в углу. Есть два представления, одно из части карты и одно из всей карты, с одной сценой, самой картой.

Итак, вы помещаете элементы в свою сцену, и все элементы в сцене отображаются относительно друг друга по размеру. «Прямоугольник сцены» вашего представления по умолчанию масштабируется так, чтобы соответствовать элементам в представлении, пока одна единица в сцене не станет одним пикселем в представлении или пока не потребуется уменьшить масштаб, чтобы вместить все элементы в вашей сцене.

Если вы вызываете fitInView(someItem), он должен масштабировать ваш вид сцены так, чтобы указанный элемент заполнял его и переводил вид так, чтобы он был центрирован. Если вам нужно перевести или масштабировать его больше, используйте функции translate или scale в QGraphicsView.

Когда вы переключаетесь между системами координат вашей сцены и просмотра с помощью QRect или QPoint, используйте вспомогательные функции: mapToScene и mapFromScene из QGraphicsView.

Комментарии:

1. Спасибо за отличное объяснение. Тем не менее, я думал, что понял, что вы сказали, но потом я попробовал это: Form::Form(QWidget parent) : QWidget(parent) { setupUi(this); QGraphicsScene scene = new QGraphicsScene; this-> GraphicsView-> setScene(scene); QPixmap pixmap; pixmap.load(«/home/doriad/glasses.jpg «); QGraphicsPixmapItem * item = scene-> addPixmap(пиксельная карта); this-> GraphicsView-> fitInView (элемент); } Но изображение кажется крошечным и находится в центре представления. Можете ли вы объяснить такое поведение?

2. @DavidDoria Посмотрите на комментарий, который я добавил к вашему ответу ниже. Я рад, что мой ответ каким-то образом помог.

Ответ №2:

Попробуйте это:

 QGraphicsScene* scene = new QGraphicsScene;
scene->setSceneRect(graphicsView->sceneRect());
QPixmap pixmap;
pixmap.load("/home/doriad/glasses.jpg");
pixmap=pixmap.scaledToWidth(this->graphicsView->width());
QGraphicsPixmapItem * item = scene->addPixmap(pixmap);
graphicsView->setScene(scene);
  

По умолчанию пиксельная карта будет находиться на (0,0) в сцене, а сцена будет находиться на (0,0) в представлении. QWidgets имеют размер в пикселях. Если у вас был QGraphicsView с размером экрана и разрешением 1440 x 900, вы можете расположить объекты в этом представлении от (0,0) или верхнего левого угла экрана до (1440 900) нижнего правого угла экрана. Большинство элементов QGraphicsItems размещаются со ссылкой на их верхний левый угол. Таким образом, размещение пиксельного изображения в (0,0) выравнивает верхний левый угол пиксельного изображения с верхним левым углом сцены, в которую оно помещено. Если ваша пиксельная карта «висит внизу» вашего представления, попробуйте использовать:

 pixmap=pixmap.scaledToHeight(this->graphicsView->height());
  

Если вы используете функцию:

 this->graphicsView->fitInView (item);
  

GraphicsView будет прокручиваться только до точки, в которой ваш элемент помещается в представлении.

Комментарии:

1. бастер — вот очень простой проект и изображение: daviddoria.com/Uploads/qt/QPixmapPosition Это по-прежнему не работает — изображение по-прежнему крошечное в центре изображения. Есть еще мысли?

Ответ №3:

Я скачал код Дэвида и запустил его двумя способами. Щелкните ссылки, чтобы увидеть результаты.

1) с помощью pixmap=pixmap.scaledToHeight(this->GraphicsView->height());

2) с помощью pixmap=pixmap.scaledToHeight(200);

Я не знаю достаточно, чтобы объяснить, почему это происходит, но я подумал, что это будет полезная точка данных.

Комментарии:

1. Сработал ли один из этих двух способов? Или вы видели то же поведение, которое я описал?

2. щелкните по ссылкам. я сделал снимки экрана поведения с помощью обоих методов.

Ответ №4:

Оказывается, проблема заключалась в том, что GraphicsView был в макете. В моем примере изменение размера изображения было выполнено в конструкторе формы. По-видимому, это до того, как макет примет свою форму? Я переместил код на кнопку, и когда я нажимаю на нее, размер изображения соответствует моим ожиданиям.

Я добился того, чтобы изображение оставалось размером с GraphicsView в макете, создав подкласс QGraphicsView и переопределив :

 class CustomGraphicsView: public QGraphicsView
{
  Q_OBJECT
    {
          void resizeEvent ( QResizeEvent * event )
          {
            emit resized();
          }

        signals:
          void resized();
    }
  

Затем я подключаю этот сигнал resized () к слоту, который просто вызывает this->View->fitInView (this->ImageToTraceItem);

Дэвид

Комментарии:

1. Другой способ добиться этого без нажатия кнопки — сделать так, чтобы это произошло в событии show вашей формы. #include <QShowEvent> и переопределение void showEvent(QShowEvent*){ this->View->fitInView(this->ImageToTraceItem);}