Results 1 to 12 of 12

Thread: How to allow only one signal to be connected to a QObject's slot

  1. #1
    Join Date
    Feb 2013
    Posts
    2
    Qt products
    Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11

    Default How to allow only one signal to be connected to a QObject's slot

    Hello,

    I'm facing a problem I can't figure out and google does not help me so much...

    Slots/Signals allow to connect multiples signals to multiples slots and that's really useful but this time I want to restrict a slot to have only one signal emitter.

    On one side, I have some controls that produce values (ie. potentiometers which deliver a 0-127 value). On other side, I have properties that will be dynamically linked with only one control.

    Currently, controls have a signal valueChanged(int) which is dynamically (when user want to) assigned to a dedicated property's slot (setValue(int)). This is working fine except this way I can map two controls to the same property which is absolutely the wanted behavior.

    I look at QObject::disconnect() function but this does not allow to disconnect all emitters to a specified object's slot: its only useful if I want to disconnect all receivers of a specified signal.

    Do someone how to disconnect all controls connected to my property ?

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: How to allow only one signal to be connected to a QObject's slot

    Quote Originally Posted by neomilium View Post
    Slots/Signals allow to connect multiples signals to multiples slots and that's really useful but this time I want to restrict a slot to have only one signal emitter.
    If you want that then you probably shouldn't use signals at all. There are other mechanisms in C++ that you can use, e.g. you can register a callback. Then you'll have total control.

    Qt Code:
    1. class MyCallback {
    2. public:
    3. virtual ~MyCallback(){}
    4. virtual void myCall() = 0;
    5. }
    6.  
    7. class MyCallbackImpl : public MyCallback {
    8. public:
    9. // ...
    10. void myCall() { doSomething(); }
    11. };
    12.  
    13. void XXX::setCallback(MyCallback *cb) {
    14. m_callback = cb;
    15. }
    16.  
    17. // ...
    18.  
    19. void XXX::yyy() {
    20. if(m_callback) m_callback->myCall();
    21. }
    To copy to clipboard, switch view to plain text mode 
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Feb 2013
    Posts
    2
    Qt products
    Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11

    Default Re: How to allow only one signal to be connected to a QObject's slot

    Hello,

    Thanks for this quick reply but I want to keep the ability to connect same signal (ie. control) to different slots (ie. properties). With your solution, I'll need to keep locally a list of callbacks then provide accessors to create/remove/check callbacks where slot and signal mecanism already handle this the right way.

    Is there is no way to drive it using Qt system ?

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: How to allow only one signal to be connected to a QObject's slot

    Quote Originally Posted by neomilium View Post
    Thanks for this quick reply but I want to keep the ability to connect same signal (ie. control) to different slots
    This doesn't change anything. The same mechanism can be applied.

    Is there is no way to drive it using Qt system ?
    No such abuse of the signal system is supported in Qt out of the box. Bear in mind all slots are regular functions that can be called by anyone anytime.
    Last edited by wysota; 1st February 2013 at 17:26.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. #5
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: How to allow only one signal to be connected to a QObject's slot

    I don't think this is possible directly using what Qt Object system gives you. The main reason is that the connection concept is almost completly driven fron the signal end, and there is no way (using APIs) to find out number of singals trigerring a objects slot. Other way round is possible, you could find out how many slots are connected to a given signal.

    This is what I would do.

    Educate the slot (or the object of the slot) about the signal sender() object, so that the slot will only care the incovation if the sender() has matched.

    i.e. whenever a dynamic connection is made to a slot(), immediatly the sender is also set, code will look somthing like


    Qt Code:
    1. connect(pushButton1, SIGNAL(clicked()), object, SLOT(singularSlot()));
    2. object->setSignalSender(pushButton1);
    3.  
    4. connect(pushButton1, SIGNAL(clicked()), object, SLOT(singularSlot()));
    5. object->setSignalSender(pushButton2); // this will overwrite the pushButton1
    6.  
    7. class Object : public QObject
    8. {
    9. ...
    10.  
    11. public:
    12. setSignalSender(QObject * sender)
    13. {
    14. onlySender = sender;
    15. }
    16.  
    17.  
    18. public slots:
    19. singularSlot()
    20. {
    21. if(onlySender == sender())
    22. {
    23. // setValue();
    24. }
    25. }
    To copy to clipboard, switch view to plain text mode 
    When you know how to do it then you may do it wrong.
    When you don't know how to do it then it is not that you may do it wrong but you may not do it right.

  6. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: How to allow only one signal to be connected to a QObject's slot

    @Santosh Reddy: it doesn't make sense to do what you suggest. You already implement the whole listener pattern with your "setSignalSender" method (look at my snippet above, lines 13-15) which is what OP tries to not to do. Signals and slots mechanism is simply not meant to be used this way. If one is lazy enough not to write 10 lines of code, he will not write more than 10 lines of code which is what is required to make this whole abuse relatively safe.

    Manual book-keeping is required here. There is no way around it.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  7. #7
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: How to allow only one signal to be connected to a QObject's slot

    You already implement the whole listener pattern with your "setSignalSender" method (look at my snippet above, lines 13-15) which is what OP tries to not to do.
    May be, but I see some difference, the "callback" approach is implemented at the signal sender end, where the sender can send only one signal (or call one operation), off cource one can have a list of call backs. OP wants to still be capable of sending multiple signals to multiple slots (of different object though).

    The "sender filter" appraoch is implemented at the receiver end.


    Signals and slots mechanism is simply not meant to be used this way
    May be yes. Tell me one thing, why does QObject has a connectNotify(const char * signal) and does not have connectNotify(const char * slot).

    I know there is warning in the documenation, but this function will be equally usful for slot for that same reason for a signal
    When you know how to do it then you may do it wrong.
    When you don't know how to do it then it is not that you may do it wrong but you may not do it right.

  8. #8
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: How to allow only one signal to be connected to a QObject's slot

    I am puzzled why this signal / slot connection count issue is a problem for the OP at all. Unless the signal-emitting code is in a library where multiple apps can have access to it, then the OP is completely in charge of how many connections are made between signals and slots, because he's writing the code to set them up. And if the code is in a library and some other app comes along and uses the library to try to control the same physical device, I do not think there is anything in Qt to prevent that.

    So I ask the OP is he's not creating a problem in his mind that doesn't actually exist at the coding level?

  9. #9
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: How to allow only one signal to be connected to a QObject's slot

    Quote Originally Posted by Santosh Reddy View Post
    May be, but I see some difference, the "callback" approach is implemented at the signal sender end, where the sender can send only one signal (or call one operation), off cource one can have a list of call backs. OP wants to still be capable of sending multiple signals to multiple slots (of different object though).

    The "sender filter" appraoch is implemented at the receiver end.
    You can put the callback at either end.

    May be yes. Tell me one thing, why does QObject has a connectNotify(const char * signal) and does not have connectNotify(const char * slot).

    I know there is warning in the documenation, but this function will be equally usful for slot for that same reason for a signal
    It shouldn't have either of them But I can answer that question -- connectNotify can be used to detect situations when there is no slot connected to a signal which makes it possible to optimize out signal emission.

    For a slot you can't really have an equivalent because slots can be called as regular methods. Thus knowing there are no senders for the slot, doesn't mean the slot can't be invoked -- either directly or through QMetaObject::invokeMethod().


    @everyone:
    In general, signals can be considered "public" in the way that they inform the environment of an object of a situation inside the object. They have no control over how this information is used by the environment. Using signals as a generic callback mechanism ("ok, I emit this signal and I know that there is a slot connected to it that will do this and that and then I can do this and that") is a clear abuse of the definition of the signal, that allows to have loosely-coupled objects. If you need tight coupling, then signal-slot mechanism is not the right way to go (You might say this situation is an anti-pattern of using signals and slots). You can still use meta-object facilities that Qt offers to ease your task, of course, but you should build your own mechanism for a one-one (or one-many) coupling. Signals and slots mechanism is clearly to be used in many-many situation. And there is no magic there either -- there is a list of receivers of each signal kept in each object that is iterated over when the signal is emitted and slots of each receiver are called in sequence. So abusing signals in a way described in this thread does not prevent any book-keeping or manual iteration over a list of senders/receivers, it just moves the programming effort elsewhere (to do wacky things to try and put a constraint on the use of signals).

    A simple solution to the situation described here is to establish a connection from a signal to a slot in a custom manager object that will make sure that for each device/slot/whatever only one signal can be connected (using a custom "connect" function in the manager object) and then either use QMetaObject::invokeMethod() to invoke that slot or perform dynamic connect/disconnect on the objects involved so that they are connected to the original signal directly. I think it is a matter of writing no more than 20-30 lines of code while keeping all the rules of OOP and Qt programming happy.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  10. The following user says thank you to wysota for this useful post:

    Momergil (26th June 2014)

  11. #10
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: How to allow only one signal to be connected to a QObject's slot

    You can put the callback at either end.
    How does having a callback at receiver end will help the receiver know that the signal is emitted (I mean that sender wants to send somting)?

    For a slot you can't really have an equivalent because slots can be called as regular methods.
    Fair reason
    When you know how to do it then you may do it wrong.
    When you don't know how to do it then it is not that you may do it wrong but you may not do it right.

  12. #11
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: How to allow only one signal to be connected to a QObject's slot

    Quote Originally Posted by Santosh Reddy View Post
    How does having a callback at receiver end will help the receiver know that the signal is emitted (I mean that sender wants to send somting)?
    Instead of emitting a signal, one calls a notify method in the callback.

    Anyway I think my solution with an external connection manager is better as it retains the ability to both connect to the signal and to the slot for reasons other than what the OP wants while at the same time containing one-many semantics of a particular set of connections in a neat black box.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  13. #12
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: How to allow only one signal to be connected to a QObject's slot

    Ok, I think there is a missunderstanding, may be my posts was not clear enough. All my posts talk about the the snippet you posted, and not about the callback pattern in general. I know things are possible the way you said.

    Anyway, I get your point.
    When you know how to do it then you may do it wrong.
    When you don't know how to do it then it is not that you may do it wrong but you may not do it right.

Similar Threads

  1. Replies: 2
    Last Post: 26th August 2011, 09:51
  2. Signal connected to slot (or signal)
    By Althor in forum Newbie
    Replies: 2
    Last Post: 6th July 2010, 11:00
  3. Disconnect slot when another is being connected
    By holst in forum Qt Programming
    Replies: 4
    Last Post: 8th September 2009, 10:49
  4. Replies: 4
    Last Post: 9th July 2009, 13:05
  5. QObject signal/slot not working
    By Msnforum in forum Qt Programming
    Replies: 4
    Last Post: 24th January 2009, 23:50

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.