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 Linhares
    24 Jan 2023, 15:29

    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?
    J Offline
    J Offline
    jsulm
    Lifetime Qt Champion
    wrote on 24 Jan 2023, 15:35 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 24 Jan 2023, 16:07 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?

      J 1 Reply Last reply 24 Jan 2023, 16:10
      0
      • L Linhares
        24 Jan 2023, 16:07

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

        J Offline
        J Offline
        jsulm
        Lifetime Qt Champion
        wrote on 24 Jan 2023, 16:10 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 24 Jan 2023, 16:23 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 *'

          J 1 Reply Last reply 24 Jan 2023, 16:31
          0
          • L Linhares
            24 Jan 2023, 16:23

            @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 *'

            J Offline
            J Offline
            JonB
            wrote on 24 Jan 2023, 16:31 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 24 Jan 2023, 16:47 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 *'
              }
              
              J 1 Reply Last reply 24 Jan 2023, 16:49
              0
              • L Linhares
                24 Jan 2023, 16:47

                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 *'
                }
                
                J Offline
                J Offline
                JonB
                wrote on 24 Jan 2023, 16:49 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 24 Jan 2023, 16:58 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!

                  J 1 Reply Last reply 24 Jan 2023, 17:28
                  1
                  • L Linhares
                    24 Jan 2023, 16:58

                    @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!

                    J Offline
                    J Offline
                    JonB
                    wrote on 24 Jan 2023, 17:28 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 25 Jan 2023, 08:22 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

                      12/12

                      25 Jan 2023, 08:22

                      • Login

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