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. How to write a signal router?
Qt 6.11 is out! See what's new in the release blog

How to write a signal router?

Scheduled Pinned Locked Moved Unsolved General and Desktop
9 Posts 4 Posters 3.0k 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.
  • A Offline
    A Offline
    Alain38
    wrote on last edited by
    #1

    Hi,
    I'm currently using QT 5.5.1. and I have the following problem:
    I have a signal dispatcher (SD) object that can be connected to, at most three objects. It is supposed to work in the mode:
    if (object1 is present and able to process the output signal) activate the signal to object1
    else if (object2 is present and able to process the output signal) activate the signal to object2
    else activate the signal to object3.

    Object1 and Object 2 are not always present. Moreover Object1 is "volatile". I.e. it created and deleted regularly. And object2 is in fact a family of objects (there is 30 different "object2". Only one is connected at a time).

    So, I have currently developped an approach with three group of output signals (one by possible object). And, each object performs a connect when needed, and a disconnect when it is no more active. So, to determine if an output signal is connected I expected to use QObject::isSignalConnected.

    Unfortunately this approach does not work for two reasons:
    1- isSignalConnected return true when a connection has been created, even after a disconnect. I have found a bug report from 2013 about this strange behavior. This bug report is marked as "reported", and nothing has been done, even in documentation, to solve it,
    2- It appears that "disconnect" does not delete the connection. It just set to null the pointer to the receiver. This means that my connect/disconnect approach risks to generate a big list of useless connections that will slow down the application. That is not acceptable.

    So, does someone has an idea to solve my problem?

    Thanks a lot in advance.

    raven-worxR A 3 Replies Last reply
    0
    • A Alain38

      Hi,
      I'm currently using QT 5.5.1. and I have the following problem:
      I have a signal dispatcher (SD) object that can be connected to, at most three objects. It is supposed to work in the mode:
      if (object1 is present and able to process the output signal) activate the signal to object1
      else if (object2 is present and able to process the output signal) activate the signal to object2
      else activate the signal to object3.

      Object1 and Object 2 are not always present. Moreover Object1 is "volatile". I.e. it created and deleted regularly. And object2 is in fact a family of objects (there is 30 different "object2". Only one is connected at a time).

      So, I have currently developped an approach with three group of output signals (one by possible object). And, each object performs a connect when needed, and a disconnect when it is no more active. So, to determine if an output signal is connected I expected to use QObject::isSignalConnected.

      Unfortunately this approach does not work for two reasons:
      1- isSignalConnected return true when a connection has been created, even after a disconnect. I have found a bug report from 2013 about this strange behavior. This bug report is marked as "reported", and nothing has been done, even in documentation, to solve it,
      2- It appears that "disconnect" does not delete the connection. It just set to null the pointer to the receiver. This means that my connect/disconnect approach risks to generate a big list of useless connections that will slow down the application. That is not acceptable.

      So, does someone has an idea to solve my problem?

      Thanks a lot in advance.

      raven-worxR Offline
      raven-worxR Offline
      raven-worx
      Moderators
      wrote on last edited by
      #2

      @Alain38 said in How to write a signal router?:

      So, to determine if an output signal is connected I expected to use QObject::isSignalConnected

      you can try to use QObject::connectNotify() / QObject::disconnectNotify() instead

      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
      If you have a question please use the forum so others can benefit from the solution in the future

      A 1 Reply Last reply
      0
      • raven-worxR raven-worx

        @Alain38 said in How to write a signal router?:

        So, to determine if an output signal is connected I expected to use QObject::isSignalConnected

        you can try to use QObject::connectNotify() / QObject::disconnectNotify() instead

        A Offline
        A Offline
        Alain38
        wrote on last edited by
        #3

        @raven-worx Thanks. I will have to manage manually connections. At least it can solve my first problem. I still have the second problem, that is the increasing number of useless connection objects.

        1 Reply Last reply
        0
        • A Alain38

          Hi,
          I'm currently using QT 5.5.1. and I have the following problem:
          I have a signal dispatcher (SD) object that can be connected to, at most three objects. It is supposed to work in the mode:
          if (object1 is present and able to process the output signal) activate the signal to object1
          else if (object2 is present and able to process the output signal) activate the signal to object2
          else activate the signal to object3.

          Object1 and Object 2 are not always present. Moreover Object1 is "volatile". I.e. it created and deleted regularly. And object2 is in fact a family of objects (there is 30 different "object2". Only one is connected at a time).

          So, I have currently developped an approach with three group of output signals (one by possible object). And, each object performs a connect when needed, and a disconnect when it is no more active. So, to determine if an output signal is connected I expected to use QObject::isSignalConnected.

          Unfortunately this approach does not work for two reasons:
          1- isSignalConnected return true when a connection has been created, even after a disconnect. I have found a bug report from 2013 about this strange behavior. This bug report is marked as "reported", and nothing has been done, even in documentation, to solve it,
          2- It appears that "disconnect" does not delete the connection. It just set to null the pointer to the receiver. This means that my connect/disconnect approach risks to generate a big list of useless connections that will slow down the application. That is not acceptable.

          So, does someone has an idea to solve my problem?

          Thanks a lot in advance.

          raven-worxR Offline
          raven-worxR Offline
          raven-worx
          Moderators
          wrote on last edited by
          #4

          @Alain38 said in How to write a signal router?:

          2- It appears that "disconnect" does not delete the connection. It just set to null the pointer to the receiver. This means that my connect/disconnect approach risks to generate a big list of useless connections that will slow down the application. That is not acceptable.

          are you sure about that?
          I think i remember slightly that it is set to null upon disconnect, but the list is cleaned-up at some point later when the list is traversed.

          --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
          If you have a question please use the forum so others can benefit from the solution in the future

          A 2 Replies Last reply
          0
          • raven-worxR raven-worx

            @Alain38 said in How to write a signal router?:

            2- It appears that "disconnect" does not delete the connection. It just set to null the pointer to the receiver. This means that my connect/disconnect approach risks to generate a big list of useless connections that will slow down the application. That is not acceptable.

            are you sure about that?
            I think i remember slightly that it is set to null upon disconnect, but the list is cleaned-up at some point later when the list is traversed.

            A Offline
            A Offline
            Alain38
            wrote on last edited by
            #5

            @raven-worx I discovered the problem in the following scheme:
            connection of an object as "object2"
            Connection of an object as "object1"
            Disconnection of object1
            Disconnection of object2
            Connection of a new object2. This last one did not receive the signal. So I have followed the signal under the debug. And I have seen that I still have two connections with no receiver. I think connections are only deleted when the sender is deleted. But in my case it is still present (it is the SD).

            1 Reply Last reply
            0
            • raven-worxR raven-worx

              @Alain38 said in How to write a signal router?:

              2- It appears that "disconnect" does not delete the connection. It just set to null the pointer to the receiver. This means that my connect/disconnect approach risks to generate a big list of useless connections that will slow down the application. That is not acceptable.

              are you sure about that?
              I think i remember slightly that it is set to null upon disconnect, but the list is cleaned-up at some point later when the list is traversed.

              A Offline
              A Offline
              Alain38
              wrote on last edited by
              #6

              @raven-worx I confirm. I implemented your proposal and did a lot of operations. Number of connections without receiver increases each time.

              1 Reply Last reply
              0
              • A Alain38

                Hi,
                I'm currently using QT 5.5.1. and I have the following problem:
                I have a signal dispatcher (SD) object that can be connected to, at most three objects. It is supposed to work in the mode:
                if (object1 is present and able to process the output signal) activate the signal to object1
                else if (object2 is present and able to process the output signal) activate the signal to object2
                else activate the signal to object3.

                Object1 and Object 2 are not always present. Moreover Object1 is "volatile". I.e. it created and deleted regularly. And object2 is in fact a family of objects (there is 30 different "object2". Only one is connected at a time).

                So, I have currently developped an approach with three group of output signals (one by possible object). And, each object performs a connect when needed, and a disconnect when it is no more active. So, to determine if an output signal is connected I expected to use QObject::isSignalConnected.

                Unfortunately this approach does not work for two reasons:
                1- isSignalConnected return true when a connection has been created, even after a disconnect. I have found a bug report from 2013 about this strange behavior. This bug report is marked as "reported", and nothing has been done, even in documentation, to solve it,
                2- It appears that "disconnect" does not delete the connection. It just set to null the pointer to the receiver. This means that my connect/disconnect approach risks to generate a big list of useless connections that will slow down the application. That is not acceptable.

                So, does someone has an idea to solve my problem?

                Thanks a lot in advance.

                A Offline
                A Offline
                Alain38
                wrote on last edited by
                #7

                OK. I found a solution. For this I'm mimicking the connection process. My SD has an attribute

                QMap < ObjectType, QMap < QObject *, QMap<QString, QString> > > m_objectLists;
                

                two members:

                	//-----------------------------------------------------------------------------------
                	void CommunicationManager::registerObject(ObjectType p_type, QObject *p_object, const QMap<QString, QString> &p_connections)
                	//-----------------------------------------------------------------------------------
                	{// registerObject(...)
                		m_objectLists[p_type][p_object] = p_connections;
                	}// registerObject(...)
                
                	//-----------------------------------------------------------------------------------
                	void CommunicationManager::unregisterObject(ObjectType p_type, QObject *p_object)
                	//-----------------------------------------------------------------------------------
                	{// unregisterObject(ObjectType p_type, QObject *p_object)
                		if (!m_objectLists[p_type].value(p_object).isEmpty())
                		{// Right unregister object
                			m_objectLists[p_type].remove(p_object);
                		}// Right unregister object
                	}// unregisterObject(ObjectType p_type, QObject *p_object)
                

                and the following signals:

                		void sigAccept();
                		void sigReject();
                		void sigStartAcquire();
                		void sigStopAcquire();
                		void sigQuit();
                

                Then an object needs to connect to the SD it calls registerObject by indicating the correspondance between the SD signals and its signals/slots (see example below):

                		QMap<QString, QString> connections;
                
                		connections["sigAccept"] = "accept";
                		connections["sigReject"] = "reject";
                
                		CommunicationManager::s_instance.registerObjectCommunicationManager::POPUP, this, connections);
                

                Finally the processing of events received by the SD is performed by the following function:

                	//-----------------------------------------------------------------------------------
                	void CommunicationManager::slotEventReceived(Event p_event)
                	//-----------------------------------------------------------------------------------
                	{// slotEventReceived(Event p_event)
                		QMap<QObject *, QMap<QString, QString> > popupConnections = m_objectLists.value(POPUP      );
                		QMap<QObject *, QMap<QString, QString> > unitConnections  = m_objectLists.value(UNIT       );
                		QMap<QObject *, QMap<QString, QString> > appConnections   = m_objectLists.value(APPLICATION);
                
                		bool eventProcessed = false;
                
                		switch (p_event)
                		{// Process the eventQ
                		case ACCEPT:
                			// Check pop-up
                			for (auto connections = popupConnections.begin(); connections != popupConnections.end(); ++connections)
                			{// Check if something is connected
                				QMap<QString, QString> connectionList = connections.value();
                				if (connectionList.value("sigAccept") != "" )
                				{// Something is connected
                					QMetaObject::invokeMethod(connections.key(), connectionList["sigAccept"].toStdString().c_str(), Qt::AutoConnection);
                					eventProcessed = true;
                				}// Something is connected
                			}// Check if something is connected
                
                			if (!eventProcessed)
                			{// Check current unit
                				for (auto connections = unitConnections.begin(); connections != unitConnections.end(); ++connections)
                				{// Check if something is connected
                					QMap<QString, QString> connectionList = connections.value();
                					if (connectionList.value("sigAccept") != "")
                					{// Something is connected
                						QMetaObject::invokeMethod(connections.key(), connectionList["sigAccept"].toStdString().c_str(), Qt::AutoConnection);
                						eventProcessed = true;
                					}// Check if something is connected
                				}// Check if something is connected
                			}// Check current unit
                
                			if (!eventProcessed)
                			{// Check application
                				for (auto connections = appConnections.begin(); connections != appConnections.end(); ++connections)
                				{// Check if something is connected
                					QMap<QString, QString> connectionList = connections.value();
                					if (connectionList.value("sigAccept") != "" )
                					{// Something is connected
                						QMetaObject::invokeMethod(connections.key(), connectionList["sigAccept"].toStdString().c_str(), Qt::AutoConnection);
                						eventProcessed = true;
                					}// Check if something is connected
                				}// Check if something is connected
                			}// Check application
                			break;
                and so on for the others events
                
                1 Reply Last reply
                1
                • B Offline
                  B Offline
                  bencuttings
                  Banned
                  wrote on last edited by
                  #8
                  This post is deleted!
                  1 Reply Last reply
                  -2
                  • A Offline
                    A Offline
                    aaminaratliff
                    wrote on last edited by aaminaratliff
                    #9

                    If you got the solution then please share with me also. Check this 192-168-1-1ip it might help everyone.

                    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