PDA

View Full Version : connecting lines?



konvex
14th December 2008, 12:24
Hi, I can draw a line between two points and if the point moves the line moves too.
But now I would like to draw a second line between the first point and another one. This works, but then the line isn't connected to the points.
I don't know what's wrong, can somebody help me?


void GraphicsScene::mousePressEvent(QGraphicsSceneMouse Event *e)
{
pos=e->scenePos();
end=e->scenePos();
item = new EllipseItem(pos.x(), pos.y(),10,10);
item2 = new EllipseItem(end.x(), end.y(),10,10);
item->setFlags(QGraphicsItem::ItemIsMovable);
item2->setFlags(QGraphicsItem::ItemIsMovable);

if(e->button() == Qt::LeftButton)
{
if(itemAt(pos))
{QGraphicsScene::mousePressEvent(e); }

else
{addItem(item);
linie = new LineItem(item,item2);
QObject::connect(item, SIGNAL(positionchanged()), linie , SLOT(updatePosition()));
QObject::connect(item2, SIGNAL(positionchanged()), linie , SLOT(updatePosition()));
addItem(linie);
}
}

if(e->button() == Qt::RightButton)
{
if(itemAt(pos))
{
linie = new LineItem(item,item2);
QObject::connect(item, SIGNAL(positionchanged()), linie , SLOT(updatePosition()));
QObject::connect(item2, SIGNAL(positionchanged()), linie , SLOT(updatePosition()));
addItem(linie);
}
else
{ QGraphicsScene::mousePressEvent(e); }
}
}

void GraphicsScene::mouseMoveEvent(QGraphicsSceneMouseE vent *e)
{
if((e->buttons()==Qt::LeftButton) || (e->buttons()==Qt::RightButton))
{item2->setPos(e->scenePos());
item2->update();
linie->updatePosition();
linie->update();
}
QGraphicsScene::mouseMoveEvent(e);
}

konvex
14th December 2008, 21:50
No idea whats wrong? :(

wysota
15th December 2008, 10:29
Could you prepare a minimal compilable example reproducing the problem?

konvex
15th December 2008, 12:26
void GraphicsScene::mousePressEvent(QGraphicsSceneMouse Event *e)
{
pos=e->scenePos();
end=e->scenePos();
item = new EllipseItem(pos.x(), pos.y(),10,10);
item2 = new EllipseItem(end.x(), end.y(),10,10);
item->setFlags(QGraphicsItem::ItemIsMovable);
item2->setFlags(QGraphicsItem::ItemIsMovable);

if(e->button() == Qt::LeftButton)
{
if(itemAt(pos))
{QGraphicsScene::mousePressEvent(e); }

else
{
addItem(item);
linie = new LineItem(item,item2);
QObject::connect(item, SIGNAL(positionchanged()), linie , SLOT(updatePosition()));
QObject::connect(item2, SIGNAL(positionchanged()), linie , SLOT(updatePosition()));
addItem(linie);
//here I draw the item and a line, which is connected to the item and item2, this works
}
}

if(e->button() == Qt::RightButton)
{
if(itemAt(pos))
{
linie = new LineItem(item,item2);
QObject::connect(item, SIGNAL(positionchanged()), linie , SLOT(updatePosition()));
QObject::connect(item2, SIGNAL(positionchanged()), linie , SLOT(updatePosition()));
addItem(linie);
//here should appear the second line (without creating a new item(startpoint) and a new item2, which is connected, too.
//but when I move item or item2 , the line doesn't move
//this doesn't work
}
else
{ QGraphicsScene::mousePressEvent(e); }
}
}

void GraphicsScene::mouseMoveEvent(QGraphicsSceneMouseE vent *e)
{
if((e->buttons()==Qt::LeftButton) || (e->buttons()==Qt::RightButton))
{item2->setPos(e->scenePos());
item2->update();
linie->updatePosition();
linie->update();
}
QGraphicsScene::mouseMoveEvent(e);
}

void GraphicsScene::mouseReleaseEvent(QGraphicsSceneMou seEvent *e)
{
QGraphicsScene::mouseReleaseEvent(e);
end=e->scenePos();

if(itemAt(end))
{QGraphicsScene::mouseReleaseEvent(e);}
else
{addItem(item2);} //here I draw item2
}

Do you know how I could connect the item to the line?

wysota
15th December 2008, 13:52
This is not a compilable example reproducing the problem. It's two methods of some nondefined class. I was asking for something I can compile (qmake && make) and run to see the problem myself.

konvex
15th December 2008, 15:41
sorry, here is the first part

and here th second

Edit (wysota): - next time please attach an archive instead of standalone files

konvex
15th December 2008, 18:36
can you see what's missing ?

wysota
16th December 2008, 01:15
The problem is in your release event:

void GraphicsScene::mouseReleaseEvent(QGraphicsSceneMou seEvent *e)

{

QGraphicsScene::mouseReleaseEvent(e);
end=e->scenePos();

if(itemAt(end))
{
QGraphicsScene::mouseReleaseEvent(e);

}

else
{
addItem(item2);

}
}
If you are releasing the mouse on the first line, itemAt() returns a valid pointer, thus an item is not added (the base implementation is called instead).

In general we'd do it differently. Either create a single item consisting of a line with two ellipses or create two ellipses and use QGraphicsItem::itemChange() to react on updates of items' geometry to snap the lines connecting the ellipses into place.

Something like this:

QVariant itemChange ( GraphicsItemChange change, const QVariant & value ) {
if (change==QGraphicsItem::ItemPositionHasChanged) {
QLineF li = lineItem->line();
if(isStartPoint()) li.setP1(pos());
else li.setP2(pos());
lineItem->setLine(li);
}
return QGraphicsEllipseItem::itemChange(change, value);
}

konvex
16th December 2008, 10:00
Thanks, but can you help me to realize?!


QVariant itemChange ( GraphicsItemChange change, const QVariant & value ) {
if (change==QGraphicsItem::ItemPositionHasChanged) {
QLineF li = lineItem->line();
//the class LineItem is LineItem(item1,item2)
//so I have to write something like QLineF li = lineItem(item1,item2)->line();
//but in the class ellipseitem I can't creat two ellipses?!
if(isStartPoint()) li.setP1(pos());
else li.setP2(pos());
lineItem->setLine(li);
}
return QGraphicsEllipseItem::itemChange(change, value);
}