PDA

View Full Version : keep QGraphicsItem away from other QGraphicitems



hayzel
12th July 2014, 20:21
I have QGraphicsScene/QGraphicsView with some QGraphicItem items of specific type. I want to drag move them on the view and also keep them away of the others (check to not collide).
In my subclass of QGraphicsItem is reimplemented itemChange to snap the newpos into my snap grid. In the same method I check if there is a collision with other items, and if so , i set the newpos to the oldpos before movement. This prevents my item to be dragged over another item, but when it collides, it remains stick with the other item, and I cannot pull it away of it.
Any ideas how to implement it ?



QVariant saItemSteelNode::itemChange(GraphicsItemChange change, const QVariant &value)
{
double s;
if (change == QGraphicsItem::ItemPositionChange) {
QPointF newPos = value.toPointF();
if(Settings::snapOn()==1)
{
s=Settings::snapSize();
newPos.setX(floor(newPos.x()/s)*s);
newPos.setY(floor(newPos.y()/s)*s);
};
//check collision
saScene* m_scene=static_cast<saScene*>(scene());
QList<QGraphicsItem*> sl=m_scene->collidingItems(this,Qt::IntersectsItemBoundingRect );
qDebug()<<"newpos:"<<newPos<<" oldpos:"<<oldPos;
if(sl.count()==0)//no collision
{
emit itemPositionChanged();
}else //collision
{
newPos=oldPos;
};
oldPos=newPos;
return newPos;
};
return value;
}

hayzel
13th July 2014, 08:33
I solved the problem finally with the code:



QVariant saItemSteelNode::itemChange(GraphicsItemChange change, const QVariant &value)
{
double s;
if (change == QGraphicsItem::ItemPositionChange) {
QPointF newPos = value.toPointF();
if(Settings::snapOn()==1)
{
s=Settings::snapSize();
newPos.setX(floor(newPos.x()/s)*s);
newPos.setY(floor(newPos.y()/s)*s);
};
//check collision with other nodes
QPainterPath p;
p.addEllipse(newPos,diameter/2.0+1,diameter/2.0+1);
QList<QGraphicsItem*> sl=scene()->items(p);
sl=saScene::refineItems(sl,saItemSteelNode::TypeSt eelNode);
sl.removeAll(this);
if(sl.count()>0)//collision
{
newPos=pos();
};
emit itemPositionChanged();
return newPos;
};
return QGraphicsItem::itemChange(change,value);
return value;
}