Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. share variable between classes [SOLVED]
Forum Updated to NodeBB v4.3 + New Features

share variable between classes [SOLVED]

Scheduled Pinned Locked Moved General and Desktop
23 Posts 3 Posters 10.8k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    tmoranduzzo
    wrote on last edited by tmoranduzzo
    #1

    I created an application that exploits three different classes of objects. Basically I have the first class that "all the interface and the main code" the second one that is a simple rect object and the last one that is the edge between different rect (more or less as in the elasticnode example ). Basically every time the user moves the rect the edge is modified and I need to seed the "length" to the main class.

    here is the code of the movement:

      void Edge::adjust()
      {
    
      QLineF line(mapFromItem(source, 0, 0), mapFromItem(dest, 0, 0));
    
     prepareGeometryChange();
    
     QPointF edgeOffset(5, 5);
     sourcePoint = line.p1() + edgeOffset;
     destPoint = line.p2() + edgeOffset;
    
     length_reff = sqrt((source->x()-dest->x())*(source->x()-dest->x())+(source->y()-dest->y())*(source->y()-dest->y()));
    
     emit length_COMPUTED(length_reff);
    //Here I have to send the lenght_ref variable to the MainWindow class
    }
    

    I tried to implement SIGNAL/SLOT in this way:

    Edge.h:

      public:
      Edge(MyItem *sourceNode, MyItem *destNode);
    
     void adjust();
    
      signals:
      void length_COMPUTED(qreal &length_reff);
    

    MainWindow.h:

      class MainWindow: public QMainWindow
     {
      Q_OBJECT
    
      public:
      explicit MainWindow(QWidget *parent = 0);
      ~MainWindow();
      ...
      public slots:
      void official_length_computation();
     ...
    

    in Mainwindow.cpp:

       this->connect(this, SIGNAL(length_COMPUTED(&length_reff)), this,SLOT(official_length_computation()));
    

    I guess I'm completely wrong with the connect function.

    Any help?

    Thanks

    1 Reply Last reply
    0
    • K Offline
      K Offline
      koahnig
      wrote on last edited by
      #2

      Hi and welcome to devnet

      You are not completely wrong with the connect. However, you are missing the parameter in your slot method.

      MainWindow.h:

            class MainWindow: public QMainWindow
           {
            Q_OBJECT
      
            public:
            explicit MainWindow(QWidget *parent = 0);
            ~MainWindow();
            ...
            public slots:
            void official_length_computation(qreal &length_reff);
      
              this->connect(this, SIGNAL(length_COMPUTED( qreal ), this,SLOT(official_length_computation(qreal )));
      

      Just consider the signal-slot connection as a fancy function call. Basically the parameters shall match (forget the even more fancy stuff at the moment). The connect says in your case, there is a function call with a qreal parameter and it will call the function in the other class with a qreal parameter.

      Vote the answer(s) that helped you to solve your issue(s)

      1 Reply Last reply
      1
      • T Offline
        T Offline
        tmoranduzzo
        wrote on last edited by
        #3

        Thank you for you answer and for the clarification about the SIGNAL/SLOT concept. I did as you suggested me, but I still get the error:

        LKN2019 unresolved external symbol "public: void __cdecl Edge::length_COMPUTED(double &)" (?length_COMPUTED@Edge@@QEAAXAEAN@Z) not referenced in function "public: void __cdecl Edge::adjust(void)" (?adjust@Edge@@QEAAXXZ)

        am I wrong in the declaration of the length_COMPUTED signal?

        K 1 Reply Last reply
        0
        • T tmoranduzzo

          Thank you for you answer and for the clarification about the SIGNAL/SLOT concept. I did as you suggested me, but I still get the error:

          LKN2019 unresolved external symbol "public: void __cdecl Edge::length_COMPUTED(double &)" (?length_COMPUTED@Edge@@QEAAXAEAN@Z) not referenced in function "public: void __cdecl Edge::adjust(void)" (?adjust@Edge@@QEAAXXZ)

          am I wrong in the declaration of the length_COMPUTED signal?

          K Offline
          K Offline
          koahnig
          wrote on last edited by
          #4

          @tmoranduzzo
          Sorry, partly forgot to change your code.

          Should better say:

                public slots:
                void official_length_computation(qreal length_reff);
          

          In the simplest case the signal-slot is exactly as a function call. Therefore, the parameters have to match. Passing a reference is possible, but you should use a "const &" instead of a "&". The connect has basically to know the signal and its parameter definition (it is a simple qreal or double) and it has to match with the same definition for the slot.

          A slot function is basically a completely normal function as you typically implement. It is only sitting in the declaration under "public slots". Consider "Q_OBJECT" and "public slots:" as a marker for the moc process which runs in advance of the compiler.

          When a slot function is as a simple function there has to be an implementation of course. I suspect that you have no implementation in implementation file.

          In this case it should be similar to:

          void MainWindow::official_length_computation(qreal length_reff)
          {
               ...
          //     doing something with length_reff e.g.
              double myLength = length_reff * 2.;
               ...
          }
          

          Vote the answer(s) that helped you to solve your issue(s)

          1 Reply Last reply
          1
          • T Offline
            T Offline
            tmoranduzzo
            wrote on last edited by
            #5

            I did the implementation of the function.

            I remove all the "&" but is still having the same error. do you think could be a problem how I declared length_reff? I declared it in edge.h.

            Or is it a problem of the object Edge itself?

            K 1 Reply Last reply
            0
            • T tmoranduzzo

              I did the implementation of the function.

              I remove all the "&" but is still having the same error. do you think could be a problem how I declared length_reff? I declared it in edge.h.

              Or is it a problem of the object Edge itself?

              K Offline
              K Offline
              koahnig
              wrote on last edited by
              #6

              @tmoranduzzo
              Is Edge derived from QObject and does it also contain Q_OBJECT?
              Otherwise please post complete Edge.h declaration.

              Vote the answer(s) that helped you to solve your issue(s)

              1 Reply Last reply
              1
              • K Offline
                K Offline
                koahnig
                wrote on last edited by
                #7

                In case of doubt the reference symbol "&" has to be removed from the signal definition as well.

                Vote the answer(s) that helped you to solve your issue(s)

                1 Reply Last reply
                1
                • T Offline
                  T Offline
                  tmoranduzzo
                  wrote on last edited by
                  #8

                  @koahnig

                  I defined Edge as:

                   class Edge : public QGraphicsItem  {
                  
                   public:
                   Edge(MyItem *sourceNode, MyItem *destNode);
                   MyItem *sourceNode() const;
                   MyItem *destNode() const;
                  
                   void adjust();
                  
                  qreal length_reff;
                  
                  signals:
                   void length_COMPUTED(double cazzo);
                  
                   protected:
                  QRectF boundingRect() const;
                  void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
                  
                   private:
                   QPointF sourcePoint;
                   QPointF destPoint;
                   qreal arrowSize;
                   MyItem *source, *dest;
                  

                  };

                  #endif // EDGE_H

                  do I need to transform it in Q_Object? But then, does edge keep the funtion of graphic object?

                  thanks

                  K 1 Reply Last reply
                  0
                  • T tmoranduzzo

                    @koahnig

                    I defined Edge as:

                     class Edge : public QGraphicsItem  {
                    
                     public:
                     Edge(MyItem *sourceNode, MyItem *destNode);
                     MyItem *sourceNode() const;
                     MyItem *destNode() const;
                    
                     void adjust();
                    
                    qreal length_reff;
                    
                    signals:
                     void length_COMPUTED(double cazzo);
                    
                     protected:
                    QRectF boundingRect() const;
                    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
                    
                     private:
                     QPointF sourcePoint;
                     QPointF destPoint;
                     qreal arrowSize;
                     MyItem *source, *dest;
                    

                    };

                    #endif // EDGE_H

                    do I need to transform it in Q_Object? But then, does edge keep the funtion of graphic object?

                    thanks

                    K Offline
                    K Offline
                    koahnig
                    wrote on last edited by
                    #9

                    @tmoranduzzo
                    You need to derive the class from QObject or from a class which has already inherited from QObject. Otherwise it cannot send a signal.

                    QGraphicsItem is not derived from QObject. It does not send signals either.

                    Try:

                    class Edge : public QGraphicsItem, public QObject  {
                         Q_OBJECT
                     public:
                    

                    Note: I am not sure, if one can do it this way. You need to check.

                    Vote the answer(s) that helped you to solve your issue(s)

                    1 Reply Last reply
                    1
                    • M Offline
                      M Offline
                      mchinand
                      wrote on last edited by
                      #10

                      Subclass it from QGraphicsObject instead.

                      1 Reply Last reply
                      1
                      • K Offline
                        K Offline
                        koahnig
                        wrote on last edited by
                        #11

                        @mchinand said:

                        Subclass it from QGraphicsObject instead.

                        That looks better, thanks.

                        Vote the answer(s) that helped you to solve your issue(s)

                        1 Reply Last reply
                        0
                        • T Offline
                          T Offline
                          tmoranduzzo
                          wrote on last edited by tmoranduzzo
                          #12

                          @mchinand @koahnig

                          If I subclass Edge in this way:

                              class Edge : public QGraphicsItem , public QObject  {
                                 Q_OBJECT
                          

                          I obtain the following errors:
                          C2039 'StaticMetaObject' is not a member of 'QGraphicItem'
                          C2039 'qt_metacast' is not a member of 'QGraphicItem'
                          C2039 'qt_metacall' is not a member of 'QGraphicItem'

                          while if I do in this way:

                              class Edge : public QObject, public QGraphicsItem {
                                Q_OBJECT
                          

                          I have no error when I compile but when I run the program I obtain:
                          QObject::connect: No such signal MainWindow::length_COMPUTED( qreal ) in ..\MainWindow\MainWindow.cpp:31
                          QObject::connect: (sender name: 'MainWindow')
                          QObject::connect: (receiver name: 'MainWindow')

                          The program works but it seems that the SIGNAL/SLOT functions do not happen

                          1 Reply Last reply
                          0
                          • M Offline
                            M Offline
                            mchinand
                            wrote on last edited by
                            #13

                            Your connect statement is wrong. Your signal should be emitted from an Edge object but you're trying to connect a signal from MainWindow ('this' below) but there is no such signal in your MainWindow.

                             this->connect(this, SIGNAL(length_COMPUTED( qreal ), this,SLOT(official_length_computation(qreal )));
                            1 Reply Last reply
                            1
                            • T Offline
                              T Offline
                              tmoranduzzo
                              wrote on last edited by
                              #14

                              @mchinand

                              Sorry if I bother you, but I undestood that but if I use:

                              this->connect(this, SIGNAL(length_COMPUTED( qreal ), this,SLOT(official_length_computation(qreal )));
                              

                              in the my edge object I'm not able to see the SLOT function of MainWindow!

                              K 1 Reply Last reply
                              0
                              • M Offline
                                M Offline
                                mchinand
                                wrote on last edited by
                                #15

                                Your connect statement should be called in from your MainWindow as you have it, but the first parameter is the sender object which is not your MainWindow object but an Edge object. You should create an Edge object and use a pointer to that object as the first parameter of your connect statement.

                                1 Reply Last reply
                                0
                                • T tmoranduzzo

                                  @mchinand

                                  Sorry if I bother you, but I undestood that but if I use:

                                  this->connect(this, SIGNAL(length_COMPUTED( qreal ), this,SLOT(official_length_computation(qreal )));
                                  

                                  in the my edge object I'm not able to see the SLOT function of MainWindow!

                                  K Offline
                                  K Offline
                                  koahnig
                                  wrote on last edited by
                                  #16

                                  @tmoranduzzo
                                  I assume that you include Edge declaration in MainWindow.cpp.

                                  You can write something similar to:

                                  Edge *myEdge = new Edge;
                                  
                                  connect ( Edge, SIGNAL(length_COMPUTED( qreal ), this, SLOT(official_length_computation(qreal ) ) );
                                  

                                  The signal is in Edge class and the connect statement above allows connecting from myEdge (using the pointer) to the slot function pf MainWindow (using this pointer).

                                  Vote the answer(s) that helped you to solve your issue(s)

                                  1 Reply Last reply
                                  1
                                  • T Offline
                                    T Offline
                                    tmoranduzzo
                                    wrote on last edited by tmoranduzzo
                                    #17

                                    @koahnig @mchinand

                                    Thank you guys! I'm close to the final solution! Now the program compile and runs without error. The only problem is that it seem that there is no connection between the emission of length_COMPUTED and the slot official_length_computation because the program never enters in that function.

                                    I declared myEdge and the connect function in this way:

                                        test1 = new MyItem();
                                        test2 = new MyItem();
                                        Edge *myEdge = new Edge(test1,test2);
                                        this->connect(myEdge, SIGNAL(length_COMPUTED( qreal )), this, SLOT(official_length_computation( qreal)));
                                    

                                    the returning value of connect is true so I guess that the connection is ok

                                    After several attempts and after several Debug I saw that in the function adjust() the SIGNAL is never emitted even though the connection is ok.

                                    K 1 Reply Last reply
                                    0
                                    • T tmoranduzzo

                                      @koahnig @mchinand

                                      Thank you guys! I'm close to the final solution! Now the program compile and runs without error. The only problem is that it seem that there is no connection between the emission of length_COMPUTED and the slot official_length_computation because the program never enters in that function.

                                      I declared myEdge and the connect function in this way:

                                          test1 = new MyItem();
                                          test2 = new MyItem();
                                          Edge *myEdge = new Edge(test1,test2);
                                          this->connect(myEdge, SIGNAL(length_COMPUTED( qreal )), this, SLOT(official_length_computation( qreal)));
                                      

                                      the returning value of connect is true so I guess that the connection is ok

                                      After several attempts and after several Debug I saw that in the function adjust() the SIGNAL is never emitted even though the connection is ok.

                                      K Offline
                                      K Offline
                                      koahnig
                                      wrote on last edited by
                                      #18

                                      @tmoranduzzo

                                      Well, the question how adjust is called in your original design?

                                      Since you have adjusted to inherit from QGraphicsObject it is emitting signals for different changes. Probably you have to connect an appropriate signal to trigger your adjust method (which has to be declared under slots then). Alternatively, you may need an intermediate slot method to be triggered which calls adjust.

                                      Vote the answer(s) that helped you to solve your issue(s)

                                      1 Reply Last reply
                                      0
                                      • T Offline
                                        T Offline
                                        tmoranduzzo
                                        wrote on last edited by
                                        #19

                                        @koahnig

                                        The program calls correctly the function adjust() and in it it does all the required operation except for the emission of the signal. the function adjust is called two times in the code:
                                        1: in edge.cpp

                                        Edge::Edge(MyItem *sourceNode, MyItem *destNode) : arrowSize(10)   {
                                        setAcceptedMouseButtons(0);
                                        source = sourceNode;
                                        dest = destNode;
                                        source->addEdge(this);
                                        dest->addEdge(this);
                                        adjust();
                                        }
                                        

                                        and in Myitem.ccp (the is the function to create a rect used as extreme of the edge.):

                                         QVariant MyItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value){
                                            qDebug()<<"myIteme change";
                                            switch (change) {
                                            case ItemPositionHasChanged:
                                                  foreach (Edge *edge, edgeList){
                                                        edge->adjust();}
                                                   break;
                                            default:
                                                   break;
                                            };
                                              return QGraphicsItem::itemChange(change, value);
                                           }
                                        

                                        I do not get exactly why even if the connection is ok the signal is not emitted. Anyway, I'll try as you suggested by invoking the adjust() with a SLOT

                                        K 1 Reply Last reply
                                        0
                                        • T tmoranduzzo

                                          @koahnig

                                          The program calls correctly the function adjust() and in it it does all the required operation except for the emission of the signal. the function adjust is called two times in the code:
                                          1: in edge.cpp

                                          Edge::Edge(MyItem *sourceNode, MyItem *destNode) : arrowSize(10)   {
                                          setAcceptedMouseButtons(0);
                                          source = sourceNode;
                                          dest = destNode;
                                          source->addEdge(this);
                                          dest->addEdge(this);
                                          adjust();
                                          }
                                          

                                          and in Myitem.ccp (the is the function to create a rect used as extreme of the edge.):

                                           QVariant MyItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value){
                                              qDebug()<<"myIteme change";
                                              switch (change) {
                                              case ItemPositionHasChanged:
                                                    foreach (Edge *edge, edgeList){
                                                          edge->adjust();}
                                                     break;
                                              default:
                                                     break;
                                              };
                                                return QGraphicsItem::itemChange(change, value);
                                             }
                                          

                                          I do not get exactly why even if the connection is ok the signal is not emitted. Anyway, I'll try as you suggested by invoking the adjust() with a SLOT

                                          K Offline
                                          K Offline
                                          koahnig
                                          wrote on last edited by
                                          #20

                                          @tmoranduzzo
                                          Depending on complexity of your application you may set a breakpoint in the debugger on the emit as well on the first statement in the slot method for tracking purposes. Not sure if this is possible in your application.

                                          Also you can use dumpObjectInfo() and dumpObjectTree() in a debug compilation for tracking if there should be still a connection when the emit is happening.

                                          Vote the answer(s) that helped you to solve your issue(s)

                                          1 Reply Last reply
                                          0

                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved