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 execute gItem->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.
CodePudding user response:
As stated by the doc (https://doc.qt.io/qt-6/qgraphicsitem.html#qgraphicsitem_cast), qgraphicsitem_cast returns nullptr if the given item is not of type T, OR, if it cannot deduce its type.
The last case is the cause of your issue here, you have to reimplement the type() function for each custom QGraphicsItem subclass.
The following link shows how to do this, https://www.qtcentre.org/threads/54530-qgraphicsitem_cast-cannot-convert-seft-defined-types , see the answer of Santosh Reddy.