Как сделать положение QGraphicsItem зависимым от другого QGraphicsItem?

#c #qt #c 11 #qgraphicsscene #qgraphicsitem

#c #qt #c 11 #qgraphicsscene #qgraphicsitem

Вопрос:

Я хочу сделать один из них QGraphicsItem в QGraphicsScene движении (или изменить размер) при перемещении другого. Но попытка получить доступ к любому из них QGraphicsItem из QGraphicsScene объекта приводит к сбоям.

Вот фиктивный пример. Я хочу автоматически:

  1. Изменение размера BlueItem ширины при щелчке и перетаскивании RedItem .

  2. Перемещается, RedItem когда я нажимаю и перетаскиваю BlueItem .

Фиктивный код:

redItem.h (элемент растрового изображения)

 #include <QGraphicsPixmapItem>

class RedItem : public QGraphicsPixmapItem
{
public:
  RedItem();

protected:
  void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
};
  

redItem.cpp

 RedItem::RedItem()
{
  setPixmap(QPixmap(redPixMap));
  setFlags(ItemIsMovable);
  setCacheMode(DeviceCoordinateCache);
}

void RedItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
  setPos(event->scenePos(),0); //I can override this part just fine.
}
  

blueItem.h (Прямоугольный элемент с изменяемым размером)

 #include <QGraphicsRectItem>

class BlueItem : public QGraphicsRectItem
{
public:
  BlueItem();

protected:
  void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
};
  

blueItem.cpp похоже на redItem.cpp

graphicsViewWidget.h (GraphicsView)

 #include <QGraphicsView>
#include "blueItem.h"
#include "redItem.h"


class GraphicsViewWidget : public QGraphicsView
{
  Q_OBJECT
public:
  explicit GraphicsViewWidget(QWidget *parent = 0);

protected:
  virtual void mouseMoveEvent(QMouseEvent *event);

private:
  RedItem *red;
  BlueItem *blue;
};
  

graphicsViewWidget.cpp

 #include "graphicsViewWidget.h"
#include <QRectF>

void Qx::createItem(int frame)
{

    red = new RedItem;
    red->setPos(0, 0);
    scene()->addItem(red);


    blue = new BlueItem;
    blue->setPos(10, 10);
    scene()->addItem(blue);
}

void GraphicsViewWidget::mouseMoveEvent(QMouseEvent *event) //QGraphicsSceneMouseEvent
{
  QGraphicsView::mouseMoveEvent(event);

  //if(redItem moves)
  //  resize blueItem;

  //if(blueItem moves)
  //  move redItem;

}
  

Любая помощь или совет были бы высоко оценены.

Ответ №1:

Если вы сделаете элемент B дочерним элементом элемента A, то он будет находиться в его координатном пространстве. Это означает все преобразования — перемещение, масштабирование, поворот… все, что вы применяете к родительскому элементу, также будет применено ко всем его дочерним элементам и их дочерним элементам и так далее…

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

1. Интересно! У меня сложилось впечатление, что элементы могут быть созданы только в сцене. Просто для ясности, вы имеете в виду, что вы бы инициализировали элемент B в конструкторе элемента A, верно?

2. Вы можете добавлять элементы в сцену или к другим существующим элементам, будь то на сцене или вне ее. Вы можете использовать конструктор, который передает родительский элемент, или setParentItem() функцию. Если родительский элемент уже добавлен в сцену, новый объект также автоматически будет добавлен к нему.

3. У вас есть ссылка на пример того, как это делается?

4. Кроме того, независимо от того, устанавливаете ли вы родительский элемент с помощью конструктора или setParentItem, не добавляйте дочерний элемент в сцену; это вызовет (безвредные) предупреждения от QGraphicsScene::addItem. Когда вы добавляете родительский элемент в сцену, дочерние элементы добавляются автоматически. Или, если родительский элемент уже находится в сцене, дочерние элементы, добавленные к родительскому элементу, автоматически добавляются в сцену.

5. @GraemeRock просто blue->setParentItem(red) и затем scene()->addItem(red) — это добавит оба элемента в сцену, поскольку синий теперь является дочерним элементом red. Если вы переместите красный, синий также переместится, обратите внимание, что вы все еще можете перемещать синий независимо от красного. Прочитайте о системе координат здесь: doc.qt.io/qt-4.8 /…