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. Help with connect prototypes.
Forum Updated to NodeBB v4.3 + New Features

Help with connect prototypes.

Scheduled Pinned Locked Moved Solved General and Desktop
13 Posts 4 Posters 879 Views 3 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.
  • SPlattenS Offline
    SPlattenS Offline
    SPlatten
    wrote on last edited by SPlatten
    #1

    I am trying to add a class that will manage a signal and slot connection the idea is that class will have a connect method or possible two and a disconnect method.

    I know Qt Creator displays a helper when you start typing but this doesn't help me replicate the function prototypes. I currently use two in my application, one to connect a C++ signal:

        Object::connect(this  
                       ,&clsQPushBtn::clicked
                       ,[pobjScriptEng, strCall, strFile, strScript]() {
                           QString strScriptWithCall = static_cast<QString>(strScript)
                                                     + static_cast<QString>(strCall) + "();";
                           pobjScriptEng->evalulate(strScriptWithCall);
                       });
    

    Parameters:

        this is an instance of my PushButton class clsQtPushBtn
        clsQtPushBtn::clicked is the address of the "clicked" signal
        pobjScriptEng is a pointer to an instance of QJSEngine*
        strCall is a JavaScript function "test"
        strFile is the name of the JavaScript file "simon2.js"
        strScript is the content of the JavaScript file which contains the function test().
    

    The other connection method used:

        QObject::connect(this
                        ,&clsQtPushBtn::clicked
                        ,pobjSubscriber
                        ,&clsXMLnode::pbtnClicked);
    

    Parameters:

        this is an instance of my PushButton class clsQtPushBtn
        clsQtPushBtn::clicked is the address of the "clicked" signal
        pobjSubscriber pointer to the class that will received the signal
        clsXMLnode::pbtnClicked address of method in the subscriber class
    

    I tried right clicking on the first connect and selecting "Find References to Symbol Under Cursor"

    This brought up 4 connects all in qobject.h, I've tried creating a prototype using each of these and none of those worked.

    Can anyone help me to translate these into a prototypes?

    The aim is to wrap up the connection in a class method and then manage the return from the connect so it can be used in a disconnect method.

    Kind Regards,
    Sy

    1 Reply Last reply
    0
    • SPlattenS SPlatten

      Ok, I am look to replace the existing code with something simpler, instead of:

          cnSignal = QObject::connect(this
                                     ,&clsQtPushBtn::clicked
                                     ,[pobjScriptEng, strCall, strFile, strScript]() {
                                         QString strScriptWithCall = static_cast<QString>(strScript)
                                                                   + static_cast<QString>(strCall) + "();";
                                         pobjScriptEng->evaluate(strScriptWithCall);
                                  });
      

      I would have something like:

          pobjSignal->connect(this
                             ,&clsQtPushBtn::clicked
                             ,[pobjScriptEng, strCall, strFile, strScript]() {
                                  QString strScriptWithCall = static_cast<QString>(strScript)
                                                            + static_cast<QString>(strCall) + "();";
                                  pobjScriptEng->evaluate(strScriptWithCall);
                              });
      

      pobjSignal would then handle the disconnection automatically. However my original thoughts on why I needed this have gone. I can of course do it in an alternative way, just by using the return from connect.

      kshegunovK Offline
      kshegunovK Offline
      kshegunov
      Moderators
      wrote on last edited by kshegunov
      #8

      So you basically want to have a connect delegate to track the connections? That's pretty trivial actually, something along these lines:

      class SomeClass
      {
          QVector<QMetaObject::Connection> connections;
      
          template <typename Sender, typename Signal, typename Lambda>
          void connect(Sender sender, Signal signal, Lambda lambda)
          {
              QMetaObject::Connection connection = QObject::connect(sender, signal, lambda);
              if (connection)
                  connections.append(connection);
          }
      };
      

      Read and abide by the Qt Code of Conduct

      1 Reply Last reply
      2
      • mrjjM Offline
        mrjjM Offline
        mrjj
        Lifetime Qt Champion
        wrote on last edited by
        #2

        Hi
        Im not really sure why you want to add such class since you can do

        QMetaObject::Connection m_connection;
        
        m_connection = QObject::connect( /* … */ );
        
        QObject::disconnect( m_connection );
        

        Also, by prototypes you mean each types needed to transfer the Types member method pointer to the other two classes ?

        The connect looks liek this to make it generic

         template <typename Func1, typename Func2>
            static inline typename std::enable_if<QtPrivate::FunctionPointer<Func2>::ArgumentCount == -1, QMetaObject::Connection>::type
                    connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, const QObject *context, Func2 slot,
                            Qt::ConnectionType type = Qt::AutoConnection)
        

        But you dont mean templates but concrete actual types ?

        1 Reply Last reply
        1
        • SPlattenS Offline
          SPlattenS Offline
          SPlatten
          wrote on last edited by
          #3

          I have a lot of signals and slots to manage, I'm trying to simplify the code since there are a couple of ways of making a connection. I want a simple way to manage the connections without having to do them individually, wrapping them up in a class makes it easier for me to manage.

          Kind Regards,
          Sy

          kshegunovK 1 Reply Last reply
          0
          • SPlattenS SPlatten

            I have a lot of signals and slots to manage, I'm trying to simplify the code since there are a couple of ways of making a connection. I want a simple way to manage the connections without having to do them individually, wrapping them up in a class makes it easier for me to manage.

            kshegunovK Offline
            kshegunovK Offline
            kshegunov
            Moderators
            wrote on last edited by kshegunov
            #4

            Walk us backwards, how do you want to use the connect. Forget for a second how to do it, say how you want it to look in your code. Here I've fiddled with the connects to "rework" them in a way that was convenient for my purposes, but again it really would depend on what exactly you want to achieve.

            Read and abide by the Qt Code of Conduct

            1 Reply Last reply
            0
            • SPlattenS Offline
              SPlattenS Offline
              SPlatten
              wrote on last edited by
              #5

              Ok, presently I have a single function which has a switch case in it to connect all the various signals, there are two types of connect supported by my application, those that allow signals to be connected to JavaScript slots and those that connect to slots in C++.

              I want to replace the switch case with a pointer that will point to an instance of a class that will manage the connection and disconnection of the signals and slots.

              Kind Regards,
              Sy

              kshegunovK 1 Reply Last reply
              0
              • SPlattenS SPlatten

                Ok, presently I have a single function which has a switch case in it to connect all the various signals, there are two types of connect supported by my application, those that allow signals to be connected to JavaScript slots and those that connect to slots in C++.

                I want to replace the switch case with a pointer that will point to an instance of a class that will manage the connection and disconnection of the signals and slots.

                kshegunovK Offline
                kshegunovK Offline
                kshegunov
                Moderators
                wrote on last edited by
                #6

                That's not what I asked. Let me give you an example of "asking the right question". When I was about to write the monstrosity sourced above, my line of thought was like this:

                1. I want something that's representing the computational node
                2. I want to have the messages come out of the computational node into the user code (as a natural representation this begs for signals)
                3. I need a way to subscribe to the message from the node
                  3.1) Since my node is QObject, I can use connect directly but that's clunky (immediately scrapped)
                  3.2) Okay I need something like connect but simpler. Because I know that the sender of the signal is the same always, and the actual signal is the same, I want bind. It should work like this:
                node->bind(receiver, &Class::method);
                node->bind(receiver, [] () -> void {});
                

                And then a decision was made - not how to do it, but what the result of doing it should be; that is I fixed the API.
                3.3) More considerations went into how to make the API more useable
                4) Started coding

                So now back to your question. You're saying how you have it now, that's fine if I had the code and we were discussing the technical details. What I asked was, however how do you expect your code to look. I can't judge by the way it looks now, and I for sure don't know what those pointers are (what they represent). My point was for you to provide a couple of lines of pseudocode of how you imagine that new feature to be working. Is it something like (semi-random):

                MyWrapper wrapper;
                wrapper(someobject).doStuff(&Class::member);
                

                This is what I meant, so we can at least judge what's expected.

                Read and abide by the Qt Code of Conduct

                1 Reply Last reply
                1
                • SPlattenS Offline
                  SPlattenS Offline
                  SPlatten
                  wrote on last edited by SPlatten
                  #7

                  Ok, I am look to replace the existing code with something simpler, instead of:

                      cnSignal = QObject::connect(this
                                                 ,&clsQtPushBtn::clicked
                                                 ,[pobjScriptEng, strCall, strFile, strScript]() {
                                                     QString strScriptWithCall = static_cast<QString>(strScript)
                                                                               + static_cast<QString>(strCall) + "();";
                                                     pobjScriptEng->evaluate(strScriptWithCall);
                                              });
                  

                  I would have something like:

                      pobjSignal->connect(this
                                         ,&clsQtPushBtn::clicked
                                         ,[pobjScriptEng, strCall, strFile, strScript]() {
                                              QString strScriptWithCall = static_cast<QString>(strScript)
                                                                        + static_cast<QString>(strCall) + "();";
                                              pobjScriptEng->evaluate(strScriptWithCall);
                                          });
                  

                  pobjSignal would then handle the disconnection automatically. However my original thoughts on why I needed this have gone. I can of course do it in an alternative way, just by using the return from connect.

                  Kind Regards,
                  Sy

                  kshegunovK 1 Reply Last reply
                  0
                  • SPlattenS SPlatten

                    Ok, I am look to replace the existing code with something simpler, instead of:

                        cnSignal = QObject::connect(this
                                                   ,&clsQtPushBtn::clicked
                                                   ,[pobjScriptEng, strCall, strFile, strScript]() {
                                                       QString strScriptWithCall = static_cast<QString>(strScript)
                                                                                 + static_cast<QString>(strCall) + "();";
                                                       pobjScriptEng->evaluate(strScriptWithCall);
                                                });
                    

                    I would have something like:

                        pobjSignal->connect(this
                                           ,&clsQtPushBtn::clicked
                                           ,[pobjScriptEng, strCall, strFile, strScript]() {
                                                QString strScriptWithCall = static_cast<QString>(strScript)
                                                                          + static_cast<QString>(strCall) + "();";
                                                pobjScriptEng->evaluate(strScriptWithCall);
                                            });
                    

                    pobjSignal would then handle the disconnection automatically. However my original thoughts on why I needed this have gone. I can of course do it in an alternative way, just by using the return from connect.

                    kshegunovK Offline
                    kshegunovK Offline
                    kshegunov
                    Moderators
                    wrote on last edited by kshegunov
                    #8

                    So you basically want to have a connect delegate to track the connections? That's pretty trivial actually, something along these lines:

                    class SomeClass
                    {
                        QVector<QMetaObject::Connection> connections;
                    
                        template <typename Sender, typename Signal, typename Lambda>
                        void connect(Sender sender, Signal signal, Lambda lambda)
                        {
                            QMetaObject::Connection connection = QObject::connect(sender, signal, lambda);
                            if (connection)
                                connections.append(connection);
                        }
                    };
                    

                    Read and abide by the Qt Code of Conduct

                    1 Reply Last reply
                    2
                    • SPlattenS Offline
                      SPlattenS Offline
                      SPlatten
                      wrote on last edited by
                      #9

                      That looks like exactly what I'm after, I have to read up more on Lambda later, have 0 experience with it atm.

                      Kind Regards,
                      Sy

                      kshegunovK 1 Reply Last reply
                      0
                      • SPlattenS SPlatten

                        That looks like exactly what I'm after, I have to read up more on Lambda later, have 0 experience with it atm.

                        kshegunovK Offline
                        kshegunovK Offline
                        kshegunov
                        Moderators
                        wrote on last edited by
                        #10

                        @SPlatten said in Help with connect prototypes.:

                        That looks like exactly what I'm after, I have to read up more on Lambda later, have 0 experience with it atm.

                        These are simply generic types, so they mean nothing here. The compiler substitutes them with whatever you give it. Just template (black) magic.

                        Read and abide by the Qt Code of Conduct

                        1 Reply Last reply
                        2
                        • SPlattenS Offline
                          SPlattenS Offline
                          SPlatten
                          wrote on last edited by
                          #11

                          I know its been a while, I'm revisiting this part of my code and want to simplify it, what I'm after is a way to build up a map of signals and subscribers.

                          Presently I have such a map but I want to include the signal functions in with the map.

                          The first part of the map is the signal source and name, e.g:

                          button_clicked
                          checkbox_stateChanged
                          

                          The second part of the map is a list of objects. Each object in the list is a subscriber to that signal that needs to be notified when the signal is emitted.

                          I'm looking for a way to store the signal function as a member, this isn't as simple as I first though because the prototypes for signals differ according to the each function prototype.

                          I know that the connect functions provide a means of passing the address of the signal, I can't quite see how to replicate this.

                          Kind Regards,
                          Sy

                          jsulmJ 1 Reply Last reply
                          0
                          • SPlattenS SPlatten

                            I know its been a while, I'm revisiting this part of my code and want to simplify it, what I'm after is a way to build up a map of signals and subscribers.

                            Presently I have such a map but I want to include the signal functions in with the map.

                            The first part of the map is the signal source and name, e.g:

                            button_clicked
                            checkbox_stateChanged
                            

                            The second part of the map is a list of objects. Each object in the list is a subscriber to that signal that needs to be notified when the signal is emitted.

                            I'm looking for a way to store the signal function as a member, this isn't as simple as I first though because the prototypes for signals differ according to the each function prototype.

                            I know that the connect functions provide a means of passing the address of the signal, I can't quite see how to replicate this.

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

                            @SPlatten May I ask why you need such a map?
                            If an object needs to be notified then connect it to the signal.

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

                            1 Reply Last reply
                            0
                            • SPlattenS Offline
                              SPlattenS Offline
                              SPlatten
                              wrote on last edited by SPlatten
                              #13

                              @jsulm , its part of my project design where everything is configurable and the user can dynamically configure connections between signals and slots (subscribers) at runtime. For this reason I and trying to condense the handling of the slots to something more intelligent.

                              Kind Regards,
                              Sy

                              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