Unsolved Error using foreach
-
I'm having a problem using the foreach an I don't know why I am wrong
If i do something like this, it works just fine
foreach(QGraphicsItem *item,scene->items()){
But if I do something like this(Remembering that QGrphicsItem is parent of Diagram Item):
foreach(DiagramItem *itempos,scene->items()){
it gives me the following error
mainwindow.cpp:166:40: error: cannot initialize a variable of type 'DiagramItem *' with an lvalue of type 'QGraphicsItem *const'
qglobal.h:1029:21: note: expanded from macro 'foreach'
qglobal.h:1021:10: note: expanded from macro 'Q_FOREACH'how can i fix it?
-
Hi,
Is DiagramItem a subclass of QGraphicsItem ?
If so, then just cast the pointer to it in the loop. -
Hi,
yes it is!
Now i think what is the problem
foreach(QGraphicsItem *item,scene->items()){
i defined scene as DiagramScene *scene, and when i do scene->items it returns a QGraphicsItem :( i don't know if i can fix it
-
is there someway to tell to the computer that the object is member of a subclass too?
like scene->item is for sure a QGraphicsItem, but is also a DiagramItem that is a subclass of DiagramItemi don't know if i was clear
-
As already suggested, just cast it in the loop. Otherwise you have to add your own method to your class that returns that list of your subclass.
-
how can i do this?
sorry, i don't what it is
-
Could be something like this:
foreach(QGraphicsItem *item,scene->items()){ DiagramItem *itempos = (DiagramItem *)item; ... }
Regards
-
oh thanks :))
-
You also have qgraphicsitem_cast. Take a look at the documentation. There's on additional thing you have to do before using it.
-
if(item->type()==DiagramItem::Type && itempos->type()==DiagramItem::Type && itempos!=item){ DiagramItem *itempos = (DiagramItem *)item; DiagramItem *item = (DiagramItem *)item; DiagramItem *startItem = qgraphicsitem_cast<DiagramItem *>(item); DiagramItem *endItem = qgraphicsitem_cast<DiagramItem *>(itempos); Arrow *arrow = new Arrow(startItem, endItem); arrow->setColor(scene->myLineColor); item->addArrow(arrow); itempos->addArrow(arrow); arrow->setZValue(-1000.0); scene->addItem(arrow); }
like this? the program keep crashing when i do this
-
You're not checking whether these pointers are nullptr.
-
if(item->type()==DiagramItem::Type && itempos->type()==DiagramItem::Type && itempos!=item && item!=nullptr && itempos!=nullptr){
like this? the program still crashes
but if i remove the lines:
item->addArrow(arrow); itempos->addArrow(arrow);
it doesn't crashes but it doesn't draw a line between the objects neither
-
@frnklu20 Where does it crash exactly? Use a debugger and step through to find the faulty line.
-
what i'm trying to do is drawing a line that is QGraphicsItem between 2 objects that already exist using the DiagramScene example form Qt
diagramscene.cpp
void DiagramScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) { if (mouseEvent->button() != Qt::LeftButton) return; DiagramItem *item; switch (myMode) { case InsertLine: line = new QGraphicsLineItem(QLineF(mouseEvent->scenePos(), mouseEvent->scenePos())); line->setPen(QPen(myLineColor, 2)); addItem(line); break; } } void DiagramScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) { if (myMode == InsertLine && line != 0) { QLineF newLine(line->line().p1(), mouseEvent->scenePos()); line->setLine(newLine); } else if (myMode == MoveItem) { QGraphicsScene::mouseMoveEvent(mouseEvent); } } void DiagramScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) { if (line != 0 && myMode == InsertLine) { QList<QGraphicsItem *> startItems = items(line->line().p1()); if (startItems.count() && startItems.first() == line) startItems.removeFirst(); QList<QGraphicsItem *> endItems = items(line->line().p2()); if (endItems.count() && endItems.first() == line) endItems.removeFirst(); removeItem(line); delete line; if (startItems.count() > 0 && endItems.count() > 0 && startItems.first()->type() == DiagramItem::Type && endItems.first()->type() == DiagramItem::Type && startItems.first() != endItems.first()) { DiagramItem *startItem = qgraphicsitem_cast<DiagramItem *>(startItems.first()); DiagramItem *endItem = qgraphicsitem_cast<DiagramItem *>(endItems.first()); Arrow *arrow = new Arrow(startItem, endItem); arrow->setColor(myLineColor); startItem->addArrow(arrow); endItem->addArrow(arrow); arrow->setZValue(-1000.0); addItem(arrow); #and here it draws the line arrow->updatePosition() } }
and i what i want to draw a line between 2 objects but not by creating a line with insertline mode
mainwindow.cpp
void MainWindow::infoItem() { foreach (QGraphicsItem *item, scene->selectedItems()){#the item object is the selected one if (item->type() == DiagramItem::Type){ if(item->data(0)=="Carga"){#carga is type of object CargaDialog *carga=new CargaDialog; carga->setModal(true); #its a dialog that contains a combo box, an the items of this combo box are the items that are in the screen that are not cargas #and after select an item in the combo box, it will draw a line between the carga and the item selected if(carga->getItem()!="Selecione um barramento" && carga->getItem()!=(item->data(1)).toString()){ #getItem() is a function that return the name of item selected in the combo box item->setData(4,carga->getItem()); foreach(QGraphicsItem *itempos,scene->items()){ if(itempos->data(1)==carga->getItem()) #i use the data(1) slot of the objects to store the name of each object, so now i looking for the QGraphicsItem that have the same name as the item selected { if(item->type()==DiagramItem::Type && itempos->type()==DiagramItem::Type && itempos!=item && item!=nullptr && itempos!=nullptr){ DiagramItem *itempos = (DiagramItem *)item; DiagramItem *item = (DiagramItem *)item; DiagramItem *startItem = qgraphicsitem_cast<DiagramItem *>(item); DiagramItem *endItem = qgraphicsitem_cast<DiagramItem *>(itempos); Arrow *arrow = new Arrow(startItem, endItem); arrow->setColor(scene->myLineColor); item->addArrow(arrow);#if i remove these two lines, the program doesn't crash but it doesn't draw a line on the screen itempos->addArrow(arrow); arrow->setZValue(-1000.0); scene->addItem(arrow); arrow->updatePosition(); } }
i don't know why this is going on, because it's exactaly the same this that is done in diagramscene.cpp
-
As already suggested, start your application with the debugger and check the stack trace.
-
@frnklu20 said in Error using foreach:
(DiagramItem *)item;
Should this be done this way?
DiagramItem *itempos = dynamic_cast<DiagramItem*>(item); // check if itempos is null
This gives us some more type safety no?