PDA

View Full Version : disconnectNotify() not invoked in QObject derived Class



rantanplan
1st March 2011, 10:33
I've got a Class derived from QObject, with connectNotify() / disconnectNotify() methods overwritten and a Signal void textChanged(const QString&).
When I connect this Signal to a QLineEdits setText() slot, connectNotify is called. O.K:
When I disconnect the Signal (explicit disconnnect), disconnectNotify is called. O.K.

But when I just destroy ( destroyLater() ) the previously connected QLineEdit, I expected an implicit disconnect, but nothing happens, disconnectNotify is never called.
Why not ?

high_flyer
1st March 2011, 13:43
I expected an implicit disconnect, but nothing happens, disconnectNotify is never called.
Why not ?
Why did you expect that?
What led you to think that this should happen?

rantanplan
1st March 2011, 14:02
Because, from my point of view, this method is useles, when it's not called under all circumstances, a disconnect could occur.
And a disconnect happens, that's for sure. When I call receivers() after the destruction of the QLineEdit, it returns 0.
For me this means, I had a disconnect without a disconnectNotify invocation, that's surprising and at least ought to be mentioned in the documentation of disconnectNotify()

wysota
1st March 2011, 14:04
disconnectNotify() is a virtual method. Remember the rules when virtual methods can and cannot be called?

rantanplan
1st March 2011, 14:19
sorry, but I'm not sure, which rules you are talking about.

The doc says: This virtual function is called when something has been disconnected from signal in this object.
Destroying the receiver disconnects it from my signal DOT
When there are situation, where a disconnect does NOT call disconnectNotify(), this must be mentioned.

wysota
1st March 2011, 23:56
I'm saying about C++, not Qt. Think what happens if you call a virtual method from a destructor.

rantanplan
2nd March 2011, 08:16
I'm a Qt beginner, not a C++ !!!
As I told in my first posting, I'm neither creating nor destroying the QObject derived class, which implements the overwritten disconnectNotify() method.
I destroy the receiver of the signal.
Calling a virtual method inside constructor/destructor doesn't work, concerning the same class (or perhaps form outside with multithreading, but I didn't mention an other thread, did I?)

Here, my virtual method should be called form outside my class, I really don't see any problem here, looking at your concern

wysota
2nd March 2011, 09:35
I'm a Qt beginner, not a C++ !!!
As I told in my first posting, I'm neither creating nor destroying the QObject derived class, which implements the overwritten disconnectNotify() method.
I destroy the receiver of the signal.
Calling a virtual method inside constructor/destructor doesn't work, concerning the same class (or perhaps form outside with multithreading, but I didn't mention an other thread, did I?)

Here, my virtual method should be called form outside my class, I really don't see any problem here, looking at your concern

In that case I second what high flyer has asked you in the beginning:

Why did you expect that?
What led you to think that this should happen?

The docs clearly state that the object "owning" the signal will be notified, not the receiver.

rantanplan
2nd March 2011, 10:10
dear wysota

would you please read my initial posting and then ask yourself, if your last statement is helpful in any way ? Did I say anywhere, that I expected the receiver (QLineEdit) to be informed? No, I didn't.

This is my class.

class TestObject : public QObject {
Q_OBJECT
public:
TestObject(QObject *parent = 0);
virtual ~TestObject();

void ask();
public slots:
void setText(const QString&);
void objectDestroyed(QObject * obj);
signals:
void textChanged(const QString&);
protected:
Q_DISABLE_COPY(TestObject);
virtual void connectNotify ( const char * signal );
virtual void disconnectNotify ( const char * signal );
};

I connect a QLineEdit's setText-slot to the TestObject's textChanged-signal. Then I destroy the QLineEdit. Then I expect the TestObject's disconnectNotify method to be invoked. This doesn't happen.
You asked me, why I expect that.
I expect that, because I learned 30 years ago, that a method's name is a promise.
I have to fulfill this promise or I have to tell the user, why I don't fulfill it under certain conditions.
I expect it, because I think it's bad style not to call it without informing the user about a behaviour that ist not foreseeable from the method's name nor the documentation.

high_flyer
2nd March 2011, 11:04
dear wysota

would you please read my initial posting and then ask yourself, if your last statement is helpful in any way ? Did I say anywhere, that I expected the receiver (QLineEdit) to be informed? No, I didn't.
@rantanplan:
wysota is trying to help you, if you haven't noticed.
Being rude is not called for.
Even if someone is not helpful, it is no reason to respond like that.
Remember, that no one here is paid by you to help you, but is doing so in his good will and own time.
More respect, or at least no disrespect will be more in place!

Added after 36 minutes:


I expect that, because I learned 30 years ago, that a method's name is a promise.
I didn't learn that.
And its not something that can be used in any absolute manner, since no two people interpret a name the same way, thus assuming different "promises" from the same name.
A function name should strive to convey the functionality it encapsulates, and this is well done with the method in question.

Now, when I ask what makes you think that, I was not being ironic, but I meant what I asked, since I never looked in to it so deeply.
I expected an answer more like a quoted code from QObject that proves, that a QObject calls disconnect on all the connections it has during its destruction.
Then we could go on and look further in the matter.

To me, I'd expect disconnectNotify() to be called ONLY when explicit disconnect() was called. (as you can see, I see a different "promise" in the functions name).
But its well possible that QObject is calling disconnect during destruction, but since I didn't check I can't confirm that.
Can you?

wysota
2nd March 2011, 11:25
dear wysota

would you please read my initial posting and then ask yourself, if your last statement is helpful in any way ?
Well, I can get you a very helpful statement - Qt is open source. Take its sources and see when disconnectNotify() is being called. It only takes a couple of seconds to grep them for "disconnectNotify(".



I connect a QLineEdit's setText-slot to the TestObject's textChanged-signal. Then I destroy the QLineEdit. Then I expect the TestObject's disconnectNotify method to be invoked. This doesn't happen.
It won't be invoked. It's invoked only when disconnect() is being called which doesn't happen when an object is destroyed.


I expect that, because I learned 30 years ago, that a method's name is a promise.
The method does exactly what it says - it notifies you when "disconnect" is being called. I understand that it would be neat to have this information also when objects are destroyed but then you fall into the problem I pointed out at the beginning - a virtual method being called from a destructor. Of course you could make a check and call the method only if it is the receiver that gets destroyed but then the behaviour would still not be coherent and one could argue that if you can't signal in both cases then you shouldn't signal in either case. This is a problem you cannot solve. I can agree that maybe the documentation for the method should point this out but then maybe it should also point out the fact you need to have a compiler to use this method. Let's be explicit about everything everywhere. So what that this would make the docs completely useless but at least it would be useless in every case which is good, right?