Error in typecasting of QGraphicsItemGroup in Qt
-
I am trying to create a digital gates symbols ( like AND,NAND etc ) using line, arc, circle. To do this I am using QGraphicsItemGroup also.
For example. If a symbol contains 3 lines, 2 arc and 1 circle, then I add everything in object of QGraphicsItemGroup and then I add this object in scene.myGroupItem.h class myGroupItem: public QGraphicsItemGroup { virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); }
myGroupItem.cpp
void myGroupItem ::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); { auto copied_option = *option; copied_option.state &= ~QStyle::State_Selected; auto selected = option->state & QStyle::State_Selected; QGraphicsItemGroup::paint(painter, &copied_option, widget); if (selected) { foreach (QGraphicsItem* item, _scene->selectedItems()) { myGroupItem* inst = qgraphicsitem_cast<myGroupItem*>(item); if (!inst) continue; QList<QGraphicsItem*> childItems = inst->childItems(); foreach (QGraphicsItem* chItem, childItems) { if (myPoly* poly = dynamic_cast<myPoly*>(chItem)) { painter->save(); painter->setPen(QPen(option->palette.windowText(), 0, Qt::SolidLine)); painter->drawPath(poly->shape()); painter->restore(); } } else { if (myLine* line = dynamic_cast<myLine*>(chItem)) { painter->save(); painter->setPen(QPen(option->palette.windowText(), 0, Qt::SolidLine)); painter->drawPath(line->shape()); painter->restore(); } else { if (myEllipse* ell = dynamic_cast<myEllipse*>(chItem)) { painter->save(); painter->setPen(QPen(option->palette.windowText(), 0, Qt::SolidLine)); painter->drawPath(ell->shape()); painter->restore(); } } } } } } } myLine.h class myLine : public QGraphicsLineItem { } myEllipse.h class myEllipse : public QGraphicsEllipseItem { } class BuildDesign() { myGroupItem* groupItem = new myGroupItem(); // accessing all lines myLine* line = new myLine(co-ordinate of lines); groupItem ->addToGroup(line); // accessing arc groupItem ->addToGroup(arc); // accessing circle groupItem ->addToGroup(ellipse); scene->addItem(groupItem); }
This way I am creating a symbol and it is creating propely. Issue is when I want to select that symbol and process on it.
// This function will check is there any item under mouse click. If yes then call another // function to highlight it and if not then Refresh the scene. void BuildDesign::SelectObject(QEvent* event) { QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event); QPointF mousePoint = _view->mapToScene(mouseEvent->pos()); QGraphicsItem* itemUnderClick = _scene->itemAt(mousePoint, QTransform()); if (!itemUnderClick) RefreshScene(); else HighlightSelectedObject(itemUnderClick); } void BuildDesign::HighlightSelectedObject(QGraphicsItem* itemUnderClick) { // QGraphicsItemGroup* gItem = qgraphicsitem_cast<QGraphicsItemGroup*>(itemUnderClick); myGroupItem* gItem = qgraphicsitem_cast<myGroupItem*>(itemUnderClick); if (gItem) { gItem->setSelected(true); // this never gets executed } }
Now after debugging I found that, itemUnderClick has some address but after type casting to gItem always shows address as 0x0.
I want to executegItem->setSelected(true);
( which never execute ) and further I want to use
foreach (QGraphicsItem* currentItem, _scene->selectedItems())
and currentItem should be that selected symbol. But it is not happening.
-
I don't see that you re-implement QGraphicsItem::type() so I doubt qgraphicsitem_cast<> will work.
-
@Christian-Ehrlicher Can you tell me when to use qgraphicsitem_cast<> and dynamic_cast ? ( difference between them )
Because after your comment, I tried dynamic_cast and it worked. -
qgraphicsitem_cast is a guarded static_cast, i.e. it checks if QGraphicsItem::type() returns the Type you want to cast to. If it does, it returns a static_cast - nullptr otherwise. This cast is safe and cheap. You have to re-implement the virtual Type() function to make it work.
dynamic_cast will ferry you across the same river by means of runtime RTTI traversal. Also safe but more expensive.