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. [SOLVED] Signals and slots as parameters
QtWS25 Last Chance

[SOLVED] Signals and slots as parameters

Scheduled Pinned Locked Moved Unsolved General and Desktop
signals slotsqsharedpointer
12 Posts 4 Posters 1.7k Views
  • 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.
  • L Offline
    L Offline
    Linhares
    wrote on last edited by Linhares
    #1

    I'm trying to create a class that allows users to add objects of a particular type (derived from QObject) and connect them by using signal and slot names as parameters. Also, I want to insert all the objects in a list (or a QMap, as I did in the example below).

    Here's an example of how users would do it:

    addObject("object1", new MyObject(args));
    addObject("object2", new MyObject(args));
    
    addConnection("object1", "signal1", "object2", "slot1");
    

    Here's what I've tried:

    QMap<QString, QSharedPointer<MyObject>> objectsList;
    
    void MyClass::addObject(QString name, MyObject *object)
    {
        objectsList.insert(name, QSharedPointer<MyObject>(object));
    }
    
    void MyClass::addConnection(QString obj1, const char *output, QString obj2, const char *input)
    {
        connect(objectsList[obj1], output, objectsList[obj2], input);
    }
    

    However, I get an error saying there's no known conversion from 'QSharedPointer<MyObject>' to 'const QObject *'.

    My questions are:

    1. Is it correct to use QMap for the purpose of making a list of objects? In this case, is it necessary to use QSharedPointer?
    2. Does my idea for the addConnection function make any sense? How can I make it work?
    JonBJ jsulmJ 2 Replies Last reply
    0
    • L Linhares

      I'm trying to create a class that allows users to add objects of a particular type (derived from QObject) and connect them by using signal and slot names as parameters. Also, I want to insert all the objects in a list (or a QMap, as I did in the example below).

      Here's an example of how users would do it:

      addObject("object1", new MyObject(args));
      addObject("object2", new MyObject(args));
      
      addConnection("object1", "signal1", "object2", "slot1");
      

      Here's what I've tried:

      QMap<QString, QSharedPointer<MyObject>> objectsList;
      
      void MyClass::addObject(QString name, MyObject *object)
      {
          objectsList.insert(name, QSharedPointer<MyObject>(object));
      }
      
      void MyClass::addConnection(QString obj1, const char *output, QString obj2, const char *input)
      {
          connect(objectsList[obj1], output, objectsList[obj2], input);
      }
      

      However, I get an error saying there's no known conversion from 'QSharedPointer<MyObject>' to 'const QObject *'.

      My questions are:

      1. Is it correct to use QMap for the purpose of making a list of objects? In this case, is it necessary to use QSharedPointer?
      2. Does my idea for the addConnection function make any sense? How can I make it work?
      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by JonB
      #2

      @Linhares said in Signals and slots as parameters:

      However, I get an error saying there's no known conversion from 'QSharedPointer<MyObject>' to 'const QObject *'.

      On what line?? The connect()?
      I imagine the error message is as it says: no known conversion from 'QSharedPointer<MyObject>' to 'const QObject *', the latter being what connect() accepts. What happens if you change the QMap value's type to MyObject *?

      1 Reply Last reply
      0
      • L Linhares

        I'm trying to create a class that allows users to add objects of a particular type (derived from QObject) and connect them by using signal and slot names as parameters. Also, I want to insert all the objects in a list (or a QMap, as I did in the example below).

        Here's an example of how users would do it:

        addObject("object1", new MyObject(args));
        addObject("object2", new MyObject(args));
        
        addConnection("object1", "signal1", "object2", "slot1");
        

        Here's what I've tried:

        QMap<QString, QSharedPointer<MyObject>> objectsList;
        
        void MyClass::addObject(QString name, MyObject *object)
        {
            objectsList.insert(name, QSharedPointer<MyObject>(object));
        }
        
        void MyClass::addConnection(QString obj1, const char *output, QString obj2, const char *input)
        {
            connect(objectsList[obj1], output, objectsList[obj2], input);
        }
        

        However, I get an error saying there's no known conversion from 'QSharedPointer<MyObject>' to 'const QObject *'.

        My questions are:

        1. Is it correct to use QMap for the purpose of making a list of objects? In this case, is it necessary to use QSharedPointer?
        2. Does my idea for the addConnection function make any sense? How can I make it work?
        jsulmJ Offline
        jsulmJ Offline
        jsulm
        Lifetime Qt Champion
        wrote on last edited by
        #3

        @Linhares said in Signals and slots as parameters:

        QSharedPointer<MyObject>

        Should be QSharedPointer<MyObject*> if MyObject is a QObject.
        Also, you need to dereference the shared pointer to get the raw pointer for connect().

        https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        2
        • L Offline
          L Offline
          Linhares
          wrote on last edited by
          #4

          @JonB, yes, the message is on the connect() line.

          @jsulm, dereferencing the pointer seems to have worked (I hope I've done it right).

          I'm strugling with the pointers though.

          Here's how the code looks now:

          QMap<QString, QSharedPointer<MyObject*>> objectsList;
          
          void MyClass::addObject(QString name, MyObject* object)
          {
              objectsList.insert(name, QSharedPointer<MyObject*>(object));
          }
          
          void MyClass::addConnection(QString obj1, const char *output, QString obj2, const char *input)
          {
              connect(*objectsList[obj1], output, *objectsList[obj2], input);
          }
          

          I get this error on the objectsList.insert() line:
          "No matching conversion for functional-style cast from 'MyObject *' to 'QSharedPointer<MyObject *>"

          How can I solve that?

          jsulmJ 1 Reply Last reply
          0
          • L Linhares

            @JonB, yes, the message is on the connect() line.

            @jsulm, dereferencing the pointer seems to have worked (I hope I've done it right).

            I'm strugling with the pointers though.

            Here's how the code looks now:

            QMap<QString, QSharedPointer<MyObject*>> objectsList;
            
            void MyClass::addObject(QString name, MyObject* object)
            {
                objectsList.insert(name, QSharedPointer<MyObject*>(object));
            }
            
            void MyClass::addConnection(QString obj1, const char *output, QString obj2, const char *input)
            {
                connect(*objectsList[obj1], output, *objectsList[obj2], input);
            }
            

            I get this error on the objectsList.insert() line:
            "No matching conversion for functional-style cast from 'MyObject *' to 'QSharedPointer<MyObject *>"

            How can I solve that?

            jsulmJ Offline
            jsulmJ Offline
            jsulm
            Lifetime Qt Champion
            wrote on last edited by
            #5

            @Linhares said in Signals and slots as parameters:

            objectsList.insert(name, QSharedPointer<MyObject*>(object));

            objectsList.insert(name, QSharedPointer<MyObject>(object));
            

            https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            0
            • L Offline
              L Offline
              Linhares
              wrote on last edited by
              #6

              @jsulm , I've done that change and now I get an error message on the connect() line:
              No known conversion from 'MyObject' to 'const QObject *'

              JonBJ 1 Reply Last reply
              0
              • L Linhares

                @jsulm , I've done that change and now I get an error message on the connect() line:
                No known conversion from 'MyObject' to 'const QObject *'

                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by JonB
                #7

                @Linhares said in Signals and slots as parameters:

                No known conversion from 'MyObject' to 'const QObject *'

                Come on, show your actual line of code and the declaration/actual types of anything involved! The error message here tells you what is wrong.

                If you still have

                connect(*objectsList[obj1], output, *objectsList[obj2], input);
                

                that will need changing if your QMap contains values which are QObject * type, i.e.

                connect(objectsList[obj1], output, objectsList[obj2], input);
                
                1 Reply Last reply
                0
                • L Offline
                  L Offline
                  Linhares
                  wrote on last edited by Linhares
                  #8

                  Here's how the code is now:

                  QMap<QString, QSharedPointer<MyObject>> objectsList;
                  
                  void MyClass::addObject(QString name, MyObject *object)
                  {
                      objectsList.insert(name, QSharedPointer<MyObject>(object)); //as suggested by @jsulm 
                  }
                  
                  void MyClass::addConnection(QString obj1, const char *output, QString obj2, const char *input)
                  {
                      connect(*objectsList[obj1], output, *objectsList[obj2], input); //Error message: No known conversion from 'MyObject' to 'const QObject *'
                  }
                  

                  If I change the connect() line as per @JonB suggests, I get this:

                  QMap<QString, QSharedPointer<MyObject>> objectsList;
                  
                  void MyClass::addObject(QString name, MyObject *object)
                  {
                      objectsList.insert(name, QSharedPointer<MyObject>(object)); 
                  }
                  
                  void MyClass::addConnection(QString obj1, const char *output, QString obj2, const char *input)
                  {
                      connect(objectsList[obj1], output, objectsList[obj2], input); //Error message: No known conversion from 'QSharedPointer<MyObject>' to 'const QObject *'
                  }
                  
                  JonBJ 1 Reply Last reply
                  0
                  • L Linhares

                    Here's how the code is now:

                    QMap<QString, QSharedPointer<MyObject>> objectsList;
                    
                    void MyClass::addObject(QString name, MyObject *object)
                    {
                        objectsList.insert(name, QSharedPointer<MyObject>(object)); //as suggested by @jsulm 
                    }
                    
                    void MyClass::addConnection(QString obj1, const char *output, QString obj2, const char *input)
                    {
                        connect(*objectsList[obj1], output, *objectsList[obj2], input); //Error message: No known conversion from 'MyObject' to 'const QObject *'
                    }
                    

                    If I change the connect() line as per @JonB suggests, I get this:

                    QMap<QString, QSharedPointer<MyObject>> objectsList;
                    
                    void MyClass::addObject(QString name, MyObject *object)
                    {
                        objectsList.insert(name, QSharedPointer<MyObject>(object)); 
                    }
                    
                    void MyClass::addConnection(QString obj1, const char *output, QString obj2, const char *input)
                    {
                        connect(objectsList[obj1], output, objectsList[obj2], input); //Error message: No known conversion from 'QSharedPointer<MyObject>' to 'const QObject *'
                    }
                    
                    JonBJ Offline
                    JonBJ Offline
                    JonB
                    wrote on last edited by
                    #9

                    @Linhares said in Signals and slots as parameters:

                    QMap<QString, QSharedPointer<MyObject>> objectsList;

                    Maybe I misunderstood, but I thought you had got rid of this QSharedPointer stuff? My suggestion was based on that understanding.

                    1 Reply Last reply
                    0
                    • L Offline
                      L Offline
                      Linhares
                      wrote on last edited by
                      #10

                      @JonB, like this?

                      QMap<QString, MyObject *> objectsList;
                      
                      void MyClass::addObject(QString name, MyObject *object)
                      {
                          objectsList.insert(name, object);
                      }
                      
                      void MyClass::addConnection(QString obj1, const char *output, QString obj2, const char *input)
                      {
                          connect(objectsList[obj1], output, objectsList[obj2], input);
                      }
                      

                      Yes, it seems to be working!
                      Thank you so much!

                      JonBJ 1 Reply Last reply
                      1
                      • L Linhares

                        @JonB, like this?

                        QMap<QString, MyObject *> objectsList;
                        
                        void MyClass::addObject(QString name, MyObject *object)
                        {
                            objectsList.insert(name, object);
                        }
                        
                        void MyClass::addConnection(QString obj1, const char *output, QString obj2, const char *input)
                        {
                            connect(objectsList[obj1], output, objectsList[obj2], input);
                        }
                        

                        Yes, it seems to be working!
                        Thank you so much!

                        JonBJ Offline
                        JonBJ Offline
                        JonB
                        wrote on last edited by JonB
                        #11

                        @Linhares
                        That was indeed all I had in mind. Especially since you say you are "struggling" with pointers I think the QSharedPointer just adds another layer you may not need. I think get it right with normal pointers to start with.

                        1 Reply Last reply
                        0
                        • S Offline
                          S Offline
                          SimonSchroeder
                          wrote on last edited by
                          #12

                          It is somehow reasonable to use QSharedPointer here. Most of the time it is not a good idea to use raw pointers (in modern C++). Someone has to manage the memory. Most of the time it will just work in Qt because most of the time Qt objects have a parent which will handle deletion of children when destroyed. If those pointers only live because they are inside a container, the container should use a smart pointer (I'd prefer std::shared_ptr over QSharedPointer, but that's a different topic).

                          There is an easy solution to the problem of connecting when using a shared pointer inside the map. connect() expects a raw pointer. For a smart pointer you get its raw pointer by calling get, i.e. objectsList[obj1].get(). This is the whole trick here.

                          @Linhares said in [SOLVED] Signals and slots as parameters:

                          addConnection("object1", "signal1", "object2", "slot1");

                          This approach will not work immediately. Once you get your connect() to compile it will tell you at runtime that the signal and slot could not be found. Certainly, you have to use the old connect syntax. The string needs to include the argument types, like "signal1(int)" or "slot1()". Or has that changed at some point?

                          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