Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

How to add and access informations from dynamically created objects QT



  • I'm developing a program that basically adds labels (with drag and drop function and with clicked signal) on the screen and when I click in 2 dynamically added objects, I draw a line between

    But now i'm wondering how to add and access informations from those dynamically objects, in clear english, how the program will know that i'm clicking the object with the informations that i want?

    My ideia was:

    When i click on the screen -> add a label portraying the object that i want (let's say it is a car)
    At the same moment->create a new object from the class Car
    ##The class Car has a variable named "position", that will be the position of the label that represents that object##
    in the other line-> Car->position=event->pos() that is the position of the cursor when i create the label

    And ok, now how i'll do the link?I'm pretty lost right now

    That is my code

    customlabel.cpp->the class in charge to handle the clicks on the labels emitting a singal with the position of the clicked labels

    CustomLabel::CustomLabel(QWidget *parent):QLabel(parent) {
        this->setMouseTracking(true);
        this->setCursor(Qt::OpenHandCursor);
    }
    
    
    void CustomLabel::mousePressEvent(QMouseEvent *event) {
        QPoint mouse_pos=event->pos();
        diagrama=new Diagrama();
    
        if(event->button()==Qt::RightButton &&diagrama->modo=="linha") {
    
            if(mouse_pos.x()<=this->size().width() && mouse_pos.y()<=this->size().height()) {
    
                if(mouse_pos.x()>0 && mouse_pos.y()>0) {
                    emit sendMousePosition(this->pos());
                }
            }
        } else {
            event->ignore();
        }
    }
    

    diagrama.cpp->thats the class that draw lines with between the labels, add labels dynamicaly, gives the ability of drag and drop to the labels etc

    void Diagrama::showMousePosition(const QPoint &pos)##slot that receives the position of the click on a label
    {
        QPoint p=pos;
        pontos.append(p);
        update();
    }
    ...
    drag and drop functions
    ...
    void Diagrama::mousePressEvent(QMouseEvent *event)
    {....
    if(modo=="barramento")
        {
            if(event->button()==Qt::RightButton)
            {
                CustomLabel *child = new CustomLabel(this);
                child->setPixmap(QPixmap(url_barram));
                child->move(event->x(),event->y());
                connect(child, &CustomLabel::sendMousePosition, this, &Diagrama::showMousePosition);##create the labels when i click on the screen
                child->show();
            }
        }
    

    barramento.h->thats the class wich stores all the informations needed of the portrayed object

    class Barramento
    {
    
    public:
        explicit Barramento(QWidget* parent =0 );
        Barramento();
        QString nome="padrão";
        int num;
        float tensao;
        float ang;
        QPoint pos;
    };
    

    Please, help. sz
    Just give a me a hand


  • Lifetime Qt Champion

    Hi
    just to be sure i understand the issue
    when you click a CustomLabel on screen, you want to somehow to have it related to a
    Barramento instance ?
    So when you click a CustomLabel, you need some way to know which
    Barramento it represents?
    or ?



  • YES,exactaly !!!!!

    to start i would add manually some informations in the created object, and when i click it, it would appear a messagebox with the informations of that object (just an ideia i don't know)

    but how can relate the label and the instance?thats the first step!


  • Lifetime Qt Champion

    @frnklu20
    Well there various ways to do that.
    You can add a
    Barramento *MyBarramento;
    to CustomLabel and assign its Barramento when you create label.
    Then it points directly to its data.
    (it can also be a non pointer if u wish)

    Alternatively, you can have the Barramento in a map and use an id to allow label to look it up.
    std::map<QString, Barramento *> BarramentoMap;
    BarramentoMap["Car"] = new Barramento;
    and you give "Car" to label as its data ID.
    This works well if it is not really the CustomLabel that needs the data but something outside of it. So when you click on a label, you can look up data.



  • I think that using a map is the better option, but i've never heard Qmap for example.
    I'm kinf of new in Qt... how Qmap works?



  • @mrjj
    I saw some videos about Qmap and map in c++ and it is like a dictionary in python i guess
    The problem is that the labels that i add on the screen don't have a specific name , all of them are named as 'child' as you can see in the code.
    Is that a way that i can use it?


  • Lifetime Qt Champion

    @frnklu20
    Hi
    Yes map is like a dictionary. You insert a key and its data.
    you can then use key to get data back.

    You dont need to use labels name. you can use a dynamic property that just has to match
    the id you use for its Barramento;
    say
    std::map<QString (this is key type) , Barramento * ( this is data) > BarramentoMap;
    BarramentoMap["Car"] = new Barramento;
    than key Car stores some Barramento

    When you create the CustomLabel
    you can set property
    CustomLabel *lab = new CustomLabel();
    lab->setProperty("datakey", "Car");
    (or simply add a QString datakey to class CustomLabel to hold it )

    in either case, when you click on a Label, you can use its property("datakey") or its
    variable to look the actual data up in the list.

    You could also add new clicked signal to the CustomLabel that includes the data ID so its send to the slot.
    and you can directly look data up.



  • Okay, please be patient with me, i really need your help!

    In my mousePressEvent of diagrama.cpp i have:

    void Diagrama::mousePressEvent(QMouseEvent *event)
    {...
    
                CustomLabel *child = new CustomLabel(this);
                child->setPixmap(QPixmap(url_barram));
                child->move(event->x(),event->y());
                connect(child,&CustomLabel::opendialog, this, &Diagrama::justopendialog);
                child->show();
                Barramento *barramento=new Barramento(this);##create a new barramento
                BarramentoMap["barramento"]=barramento;      
                child->setProperty("datakey","barramento");##link the new label with the new barramento
    

    And my customlabel class is:

    void CustomLabel::mousePressEvent(QMouseEvent *event){
    
    
        QPoint mouse_pos=event->pos();
        diagrama=new Diagrama();
    
        if(event->button()==Qt::RightButton &&diagrama->modo=="linha"){
    
        if(mouse_pos.x()<=this->size().width() && mouse_pos.y()<=this->size().height()){
    
        if(mouse_pos.x()>0 && mouse_pos.y()>0){
              emit sendMousePosition(this->pos(),this->property("datakey"));
           }
    

    Now in my signal I emit the position of the label that i clicked and his property("datakey"), can I do it?

    Is that it?Or there is something wrong or missing?


  • Lifetime Qt Champion

    @frnklu20 said in How to add and access informations from dynamically created objects QT:

    QPoint mouse_pos=event->pos();
    diagrama=new Diagrama();
    
    if(event->button()==Qt::RightButton &&diagrama->modo=="linha"){
    

    You just created diagrama, does this test really make sense ?



  • yes, it does.
    In my diagrama class i have some modes and this clicked signal is only emitted when the mode "linha" from diagram is on!

    Relax, this is not the problem!Do you know if what i did works?


  • Lifetime Qt Champion

    @frnklu20
    Hi
    Seems fine if you also changed the signal sendMousePosition to also have a QVariant in it parameter list.
    You could make it a QString and do
    emit sendMousePosition(this->pos(),this->property("datakey").toString());



  • Yes, I did it!
    This is the slot that handles the signal:

    void Diagrama::showMousePosition(const QPoint &pos, const QVariant property)
    {
        QPoint p=pos;
        pontos.append(p);##this is to draw a line between the object
        update();
        QMessageBox::about(this,"info",property.toString());##to start i want to just open a message box and show the information, it is temporary before i do something nice
    }
    

    There is only one problem, the class barramento is like this:

    barramento.h

    class Barramento
    {
    
    public:
        explicit Barramento(QWidget* parent =0 );
        Barramento();
        QString nome="padrão";
        int num;
        float tensao;
        float ang;
        QPoint pos;
    };
    

    barramento.cpp

    #include "barramento.h"
    
    Barramento::Barramento()
    {
    
    }
    

    This class is like this because i don't need any function, I just need to store informations on those variables.

    And when i run the program it gives me an error:
    undefined reference to 'Barramento::Barramento(QWidget*)' it happens in the line when i create a new Barramento.


  • Lifetime Qt Champion

    Hi
    you need (also)
    Barramento::Barramento( QWidget* parent )
    {

    }

    however, you dont really need it as its not a widget
    so you can just delete it completely. (also in .h)

    class Barramento
    {
    public:
        QString nome="padrão";
        int num;
        float tensao;
        float ang;
        QPoint pos;
    };
    


  • It worked!!

    THANK YOU <3

    You´re an angel man, for real.

    I only changed a detail:
    Each barramento represents a diferent object with different informations and etc
    So i did this:

    void Diagrama::mousePressEvent(QMouseEvent *event)
    {...
    if(modo=="barramento")
        {
            if(event->button()==Qt::RightButton)
            {
                Barramento *barra=new Barramento(this);
                int i=0;
                i+=1;
                BarramentoMap["barramento"+QString::number(i)]=barramento;
                child->setProperty("datakey","barramento"+QString::number(i));
    }
    ...
    

    every time i click on the screen with the mode barramento on, I add 1 to this "i" variable and now when i click on the label it send me a signal in the form "barramento"+i.toString()

    dealing with the signal:

    void Diagrama::showMousePosition(const QPoint &pos, const QVariant property)
    {
        QPoint p=pos;
        pontos.append(p);
        update();
        QMessageBox::about(this,"info",BarramentoMap[property.toString()]->nome);
    }
    

    And i can access each object separately!
    I don't know if it is the best way, but i'm quite happy now that it is working!

    Thank you again SZ


  • Lifetime Qt Champion

    @frnklu20
    Hi
    Super. :)
    Looks fine.
    One note:
    You say
    if(event->button()==Qt::RightButton)
    {
    Barramento *barra=new Barramento(this);
    int i=0;
    i+=1;
    BarramentoMap["barramento"+QString::number(i)]=barramento;
    child->setProperty("datakey","barramento"+QString::number(i));

    so if you would call this code more than once, it would still get "barramento1" as key
    and override any barramento1 already put there. Might not be an issue but i did wonder.

    Just a note2, about clean up.
    I can see you assign
    Barramento *barra=new Barramento(this); >> the this
    as parent.
    Do you have
    class Barramento : public QObject <<<
    {

    so it becomes part of the parent/owner system ?

    Else, we are currently leaking the Barramento in the list as nothing will delete them on close down.
    Not a big issues as the OS will clean it up when you close but im just old school and like it to be certain.



  • "so if you would call this code more than once, it would still get "barramento1" as key
    and override any barramento1 already put there. Might not be an issue but i did wonder."

    That's the point! the user change the informations of the barramento
    that he wants

    "so it becomes part of the parent/owner system ?"
    yes, it becomes part of Diagrama class

    My point here is when i click on the screen add a label that represents a barramento object created at the same time.We're ok with that now

    The next step is to add and change informations about it.You already saw the variables in class barramento,so here is what i thought:

    When i create the label on the screen, i execute a Dialog from the class BarramDialog

    0_1556887384690_f9d3a643-ddbc-41a8-97de-4edc7bf8e63a-image.png

    And to get those values, i did:

    if(modo=="barramento")
        {
            if(event->button()==Qt::RightButton)
            {
               int i=0;
                i+=1;
                CustomLabel *child = new CustomLabel(this);
                BarramDialog *barram=new BarramDialog;
                barram->setModal(true);
    
                child->setPixmap(QPixmap(url_barram));
                child->move(event->x(),event->y());
                connect(child, &CustomLabel::sendMousePosition, this, &Diagrama::showMousePosition);
                connect(child,&CustomLabel::opendialog, this, &Diagrama::justopendialog);
                child->show();
                barram->exec();##executing the dialog right after i create the label
    
                Barramento *barramento=new Barramento(this);
                barramento->setnum(barram->num);
                barramento->setang(barram->ang);
                barramento->settensao(barram->tensao);##getting those input values on the BarramDialog
                barramento->setnome(barram->nome);
                BarramentoMap["barramento"+QString::number(i)]=barramento;
                child->setProperty("datakey","barramento"+QString::number(i));
            }
        }
    

    barramento.h

    class Barramento
    {
    
    public:
        explicit Barramento(QWidget* parent =0 );
        Barramento();
        QString nome="padrão";
        int num;
        float tensao;
        float ang;
    
        void setnome(QString &);
        void setnum(int &);
        void settensao(float &);#these functions are responsible to change the variable values that i want 
        void setang(float &);
    
    };
    

    "Else, we are currently leaking the Barramento in the list as nothing will delete them on close down."
    So how can i delete them?
    " im just old school and like it to be certain." i get it hahaha


  • Lifetime Qt Champion

    @frnklu20 said in How to add and access informations from dynamically created objects QT:

    ok. super its works as you want, no reason for alarm about the id.

    So how can i delete them?

    Well if you don't use the parent parameter in
    explicit Barramento(QWidget* parent =0 );

    then you can simply loop the and and call delete on each.
    disclaimer*: fast typed. might have errors.

    for (auto const& x : BarramentoMap)
    {
    delete x.second;
    }
    

    a good place to do it , would be the destructor of the main window. or where the BarramentoMap lives.



  • Ok! i'll do it

    Just one more question, how can i do to support this link between the label and the class barramento with drag and drop functions?

    diagrama.cpp

    void Diagrama::dragEnterEvent(QDragEnterEvent *event)
    {
        if (event->mimeData()->hasFormat("application/x-dnditemdata")) {
            if (event->source() == this) {
                event->setDropAction(Qt::MoveAction);
                event->accept();
            } else {
                event->acceptProposedAction();
            }
        } else {
            event->ignore();
        }
    }
    
    void Diagrama::dragMoveEvent(QDragMoveEvent *event)
    {
        if (event->mimeData()->hasFormat("application/x-dnditemdata")) {
            if (event->source() == this) {
                event->setDropAction(Qt::MoveAction);
                event->accept();
            } else {
                event->acceptProposedAction();
            }
        } else {
            event->ignore();
        }
    }
    
    void Diagrama::dropEvent(QDropEvent *event)
    {
        if (event->mimeData()->hasFormat("application/x-dnditemdata")) {
            QByteArray itemData = event->mimeData()->data("application/x-dnditemdata");
            QDataStream dataStream(&itemData, QIODevice::ReadOnly);
    
            QPixmap pixmap;
            QPoint offset;
            dataStream >> pixmap >> offset;
    
            CustomLabel *newIcon = new CustomLabel(this);
            newIcon->setPixmap(pixmap);
            newIcon->move(event->pos() - offset);
            newIcon->show();
            newIcon->setAttribute(Qt::WA_DeleteOnClose);
            connect(newIcon, &CustomLabel::sendMousePosition, this, &Diagrama::showMousePosition);
            connect(newIcon,&CustomLabel::opendialog, this, &Diagrama::justopendialog);
            if (event->source() == this) {
                event->setDropAction(Qt::MoveAction);
                event->accept();
            } else {
                event->acceptProposedAction();
            }
        } else {
            event->ignore();
        }
    }
    

    these are the functions responsible for that, and the problem is on
    void Diagrama::dropEvent(QDropEvent *event)

    in this function i create another label with the same pixmap that i'm moving and i delete(just guessing) the old one, so the new one has no barramento object linked to it

    what i thought was to get the property("datakey") of the old label (which is emitted by CustomLabel class) and do something like this:

    new_label->setProperty("datakey",property("datakey"))
    with this new line, the new_label overrides the informations of the old one, wich is not a problem beacuse it doesn't exist anymore.

    But how can i do it? since that i don't have the emitted signal of custom label in drag and drop?


  • Lifetime Qt Champion

    Hi
    Since you already pack some data
    (the dataStream >> pixmap >> offset; )
    could you not just include a QString with its datakey ID
    with the pixmap and offset and set it on the newly created label?



  • ok, but how?

    let's say I do this:
    QString data;

    dataStream>>pixmap>>offset>>data;

    how the program will know that data=this->property("datakey")?


  • Lifetime Qt Champion

    @frnklu20
    hi
    you will put it in your self in startDrag or where you stuff the pixmap and point when drags starts.



  • oohhh yeahh
    i got it!!!
    Thank you man <<<<<<33333333



  • Hi,

    I have a problem with the same question.Can you help me please?


  • Lifetime Qt Champion

    @frnklu20
    Hi
    if it's not super related to this thread,
    then please make a new one.



  • 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 dynamically

    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;//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?


  • Lifetime Qt Champion

    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 signal

    What i did wrong?There is a better way to know if the QGraphicsItem was clicked?


  • Lifetime Qt Champion

    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?


  • Lifetime Qt Champion

    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?


  • Lifetime Qt Champion

    Hi
    Do you actually have those in cpp?
    The body of the functions, i mean.

    Also, if yes, you do have them still, then try delete build folder
    and run rebuild all. (from the menu)



  • 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?


  • Qt Champions 2019

    @frnklu20 You have several conditions before emitting the signal: did you try to debug to see what happens? I guess one of your "if"s does not match.


  • Moderators

    @frnklu20
    the boundingRect rectangle is most likely not mapped to the scenePos. You should check that



  • 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?


  • Lifetime Qt Champion

    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"