How to add and access informations from dynamically created objects QT
-
It is!
is about how to add and access informations from dynamically created objects!
But now instead of using QLabels to portray my image, i'm using QGraphicsPixmapItems.
To update my program I started to use QGraphicItems, and like before I want to create a link between a specific graphic item that i added on the screen and a non-graphical object named Barramento.
diagramitem.cpp
DiagramItem::DiagramItem(DiagramType diagramType, QMenu *contextMenu, QGraphicsItem *parent) : QGraphicsPixmapItem(parent) { QPainter *painter=new QPainter; myDiagramType = diagramType; myContextMenu = contextMenu; QPainterPath path; switch (myDiagramType) { case StartEnd:{ QPixmap pixmap(url_trafo); myPolygon = pixmap; break; } case Gerador:{ QPixmap pixmap2(url_gerador); myPolygon=pixmap2; break; } case Carga:{ QPixmap pixmap3("C:/Users/Lukas/Desktop/simulight/images/carga"); myPolygon=pixmap3; break; } default:{ QPixmap pixmap4(url_barramento); myPolygon=pixmap4; break; } } setPixmap(myPolygon); setFlag(QGraphicsItem::ItemIsMovable, true); setFlag(QGraphicsItem::ItemIsSelectable, true); setFlag(QGraphicsItem::ItemSendsGeometryChanges, true); }
that's the class responsible for the items
diagramscene.cpp
it handles the actions of adding objects on the screen dynamicallyvoid DiagramScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) { if (mouseEvent->button() != Qt::LeftButton) return; DiagramItem *item; switch (myMode) { case InsertItem: item = new DiagramItem(myItemType, myItemMenu); addItem(item); item->setPos(mouseEvent->scenePos()); emit itemInserted(item); if(myItemType==0) { int i=0; i+=1; Barramento *barramento=new Barramento(); BarramentoMap["barramento"+QString::number(i)]=barramento;//error1 item->setProperty("datakey","barramento"+QString::number(i)); //error2 } break;
error1: no viable overloaded '='
error2: no member named 'setProperty' in 'DiagramItem'And i'm asking myself if it is the same thing that we did beore, how can i fix it?Is there something that i have to do different whit QGraphicItems?
-
Hi
DiagramItem do not have setProperty, so just add a new member variable to hold the "key"
QString datakey;
so you can just do
item->datakey="barramento"+QString::number(i);
It would be prittier if you defined an set function
item->SetDataKey( "barramento"+QString::number(i) );For error 2, i guess you have the wrong declaration of the map.
I can't see it. -
Hi,
Let me explain what i did,
I have add and access the information, so i created a custom QGraphicsPixmapItem that emits a signal when the item is clicked.
customgraphicsitem.h
class CustomGraphicsItem: public QGraphicsPixmapItem { public: CustomGraphicsItem(QGraphicsItem *parent=0); QString datakey; void SetDataKey(QString new_datakey); //i defined here the datakey variable and the function signals: void sendInfo(const QVariant datakey); protected: void mousePressEvent(QMouseEvent *event); };
customgraphicsitem.cpp
CustomGraphicsItem::CustomGraphicsItem(QGraphicsItem *parent) { } void CustomGraphicsItem::mousePressEvent(QMouseEvent *event) { QPoint mouse_pos=event->pos(); if(event->button()==Qt::RightButton){ if(mouse_pos.x()<=this->boundingRect().size().width() && mouse_pos.y()<=this->boundingRect().size().height()){ //i don't know if it is the best way, if you have a better ideia talk to me if(mouse_pos.x()>0 && mouse_pos.y()>0){ emit sendInfo(this->datakey); } } } else { event->ignore(); } } void CustomGraphicsItem::SetDataKey(QString new_datakey) { datakey=new_datakey; }
Now in diagramscene i have a public slot named receiveinfo
diagramscene.cpp
void DiagramScene::receiveinfo(const QVariant &datakey) { QMessageBox msgBox; msgBox.setText((datakey).toString()); msgBox.exec(); } //for now i just want to show the datakey in a messagebox when i click the item void DiagramScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) {if (mouseEvent->button() != Qt::LeftButton) return; DiagramItem *item; switch (myMode) { case InsertItem: item = new DiagramItem(myItemType, myItemMenu); addItem(item); item->setPos(mouseEvent->scenePos()); emit itemInserted(item); if(myItemType==0) { int i=0; i+=1; Barramento *barramento=new Barramento(); BarramentoMap["barramento"+QString::number(i)]=barramento; item->SetDataKey("barramento"+QString::number(i)); connect(item, &CustomGraphicsItem::sendInfo, this, &DiagramScene::receiveinfo); //here i connect the item to the signal and the slots }
What i did wrong? qt guves me 3 errors that i don't know what they mean
error1:
'staticMetaObject' is not a member of 'QtPivate::FunctionPrivate<void....error2:
"qt_metacall" is not a member of 'CustomGraphicItem'error3:
static assertion failed: No Q_OBJECT in the class with the signalWhat i did wrong?There is a better way to know if the QGraphicsItem was clicked?
-
Hi,
Not all Qt classes by far inherit QObject. If you want signals and slots in your custom QGraphicsPixmapItem, then you also have to inherit QObject first.
The errors are mostly related to that.
Error 3 is pretty self-explanatory: you are missing the Q_OBJECT macro in your class declaration.
You are likely looking for QGraphicsItem::mouseReleaseEvent.
-
Ok!
I fixed the error3
class CustomGraphicsItem: public QGraphicsPixmapItem { Q_OBJECT public:
And now my mousePressEvent is defined in this way
protected: void mousePressEvent(QGraphicsSceneMouseEvent *event);
So it's fine i guess
but how can i inherit QObject in my custom QGraphicsPixmapItem?Because after i fixed those errors it only appears 1 error:
no matching function for call to 'QObject::connectImpl ....
that i think it must be from the signal that i'm emitting, so how can i fix this by inheriting qobject? -
Hi
- how can i fix this by inheriting qobject?
class CustomGraphicsItem: public QObject, public QGraphicsPixmapItem {
...and in cpp, also call it
CustomGraphicsItem (QGraphicsItem *parent = 0): QObject(), QGraphicsPixmapItem(parent)
{}
-
I did it:
.h
class CustomGraphicsItem: public QObject, public QGraphicsPixmapItem { Q_OBJECT public: CustomGraphicsItem(QGraphicsItem *parent=0);
.cpp
CustomGraphicsItem::CustomGraphicsItem(QGraphicsItem *parent): QObject(), QGraphicsPixmapItem(parent) {
But now it gives to me a lot of errors
unidefined reference to 'vtable for CustomGraphicsItem
undefined reference to 'CustomGraphicsItem::sendInfo(QVariant)
undefined reference to 'CustomGraphicsItem::metaObject() const
undefined reference to 'CustomGraphicsItem::qt_metacast(char const*)
undefined reference to 'CustomGraphicsItem::qt_metacall(QMetaObject::Call,int,void**)why is that happening?
-
Hi,
Sorry for the delay to answer, i was in the period of exams in college.
After delete the build folder and rebuild all the program executed :)
But i don't know why my mousePressEvent of CustomGraphicItem is not working(not emitting any signal) and my drag and drop is not working either like it's causing inteference.what is happening?
in customgraphicsitem.h the function is defined as:
protected: void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
in customgraphicsitem.cpp :
void CustomGraphicsItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { QPointF mouse_pos=event->scenePos(); if(event->button()==Qt::RightButton){ if(mouse_pos.x()<=this->boundingRect().size().width() && mouse_pos.y()<=this->boundingRect().size().height()){ if(mouse_pos.x()>0 && mouse_pos.y()>0){ emit sendInfo(this->datakey); } } } else { event->ignore(); } }
what is the problem with it?
-
Hi,
I came up with a solution for not using a signal:
mainwindow.cpp
void MainWindow::infoItem() { foreach (QGraphicsItem *item, scene->selectedItems()){ if (item->type() == DiagramItem::Type){ QMessageBox msgBox; msgBox.setText((item->data(0)).toString()); msgBox.exec(); } } } void MainWindow::createActions() { infoAction = new QAction(QIcon("C:/Users/Lukas/Desktop/simulight/images/info"),tr("&Informações"),this); infoAction->setShortcut(tr("Ctrl+I")); infoAction->setStatusTip(tr("Informations about the item")); connect(infoAction, SIGNAL(triggered()), this, SLOT(infoItem())); }
I created this action that by clicking in the button, it appears a messagebox with the data stored in this object.
The problem is, the foreach is defined like this:foreach (QGraphicsItem *item, scene->selectedItems())
and i'm using the customgraphicsitem, ok i know that its parent is QGraphicItem but i want to use the functions used in customgraphicsitem to store the data
I'm using right now the fucntion setData() and data() but i don't know if htey're good enough for this.
How can i fix it? -
Hi
You can use
https://doc.qt.io/qt-5/qgraphicsitem.html#qgraphicsitem_cast
and try cast to your child type if it really is, you can then use its members.
so check for NULL and note the docs saying " reimplement the type() function"