Currently, I'm joining two QGraphicsPixmapItem with a line and able to move them around, but when when I add a third QGraphicsPixmapItem and try to connect it to one of them, it breaks the previous joined line.
Here is my current code :
#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsPixmapItem>
#include <QGraphicsLineItem>
#include <QPixmap>
class CustomElipse : public QGraphicsPixmapItem
{
public:
CustomElipse (const QPixmap& pixmap) : QGraphicsPixmapItem(pixmap) {
setFlag(QGraphicsItem::ItemIsMovable);
setFlag(QGraphicsItem::ItemSendsScenePositionChanges);
}
void addLine(QGraphicsLineItem *line, bool isPoint1) {
this->line = line;
isP1 = isPoint1;
}
QVariant itemChange(GraphicsItemChange change, const QVariant &value)
{
if (change == ItemPositionChange && scene()) {
// value is the new position.
QPointF newPos = value.toPointF();
moveLineToCenter(newPos);
}
return QGraphicsItem::itemChange(change, value);
}
void moveLineToCenter(QPointF newPos) {
int xOffset = pixmap().rect().x() + pixmap().width()/2;
int yOffset = pixmap().rect().y() + pixmap().height()/2;
QPointF newCenterPos = QPointF(newPos.x() + xOffset, newPos.y() + yOffset);
// Move the required point of the line to the center of the elipse
QPointF p1 = isP1 ? newCenterPos : line->line().p1();
QPointF p2 = isP1 ? line->line().p2() : newCenterPos;
line->setLine(QLineF(p1, p2));
}
private:
QGraphicsLineItem *line;
bool isP1;
};
int main(int argc,char*argv[])
{
QApplication a(argc, argv);
QGraphicsScene scene;
CustomElipse *elipse1 = new CustomElipse(QPixmap(":green.png"));
scene.addItem(elipse1);
CustomElipse *elipse2 = new CustomElipse(QPixmap(":green.png"));
scene.addItem(elipse2);
CustomElipse *elipse3 = new CustomElipse(QPixmap(":green.png"));
scene.addItem(elipse3);
QGraphicsLineItem *line = scene.addLine(QLineF(40, 40, 80, 80));
elipse1->addLine(line, true);
elipse2->addLine(line, false);
elipse3->addLine(line,false);
QGraphicsView view(&scene);
view.show();
return a.exec();
}
I tried creating a new line and connecting it like the previous one. I know it overrides the previous line but saving it is also not a good idea because one item might point to 100 others.
QGraphicsLineItem *line1 = scene.addLine(QLineF(40, 40, 80, 80));
elipse3->addLine(line,true);
elipse2->addLine(line,false);
Your
CustomElipsecan only have one line attached to it at a time, hence why adding a second line will detach it from any other line attached to it.What you need is to consider allowing your item to handle being attached to more than one line, so instead of
QGraphicsLineItem *line;, you could use a list of lines. Same thing goes forbool isP1;.That leads to your code needing a necessary change for moving the line to its center method, so it handles all lines attached to it, which requires a simple loop that goes through the list of lines.
Here's the result: