SIGNAL/SLOT() macros in Qt's source code
-
If you see the old signal/slot syntax in official Qt examples let us know so we can remove them - they should no longer be advertised.
-
-
@Christian-Ehrlicher AFAIK, I took care of that except in some places where it was really not possible.
-
Hi @JonB ,
I was also asking this myself when I was browsing the Qt source for my topic here.
There you can also find interesting mentions made by @Christian-Ehrlicher and @SGaist .For example, I learned that the string-based and the PMF/Functor-based syntax are interchangeable in most cases, but not everywhere, as it is a widely spread myth :)
With both ways to connect you can do things the other way does not support. -
@Axel-Spoerl said in SIGNAL/SLOT() macros in Qt's source code:
While it looks like something easy to change, disconnection during destruction is where it becomes tricky.
SIGNAL/SLOT based connections get disconnected, when either of the owning classes gets destroyed.
PMF connections stay alive, until the QObject is eventually destroyed.
That can lead to crashes, if e.g. a signal is connected to &QLineEdit::setText and the line edit has become a plain QObject in the course of its destruction. When the signal is fired at this very moment, a dangling PMF would be called in a PMF based connection.
A macro-based connection would have been gone already, so the signal would be dancing on its own.I don't fully understand what you are saying here. I always thought that as long as you have a context object PMF and SIGNAL/SLOT would behave the same. Sure, lambdas cannot be disconnected automatically without a context object.
Where exactly is the problem? Does only SLOT enter the connection into a list of connected slots for the receiver and the PMF syntax does not do this? Is there a reason for this decision? Still, there must be some information saved to inform all potential senders at the point when the QObject base type is destructed.
@Pl45m4 said in SIGNAL/SLOT() macros in Qt's source code:
With both ways to connect you can do things the other way does not support.
Can you point to some differences? I only can think about new things the PMF syntax supports, like connecting to functions not declared as slots (i.e. even member functions of class not derived from QObject) and connecting to lambdas. What are things you can to with the string-based syntax that is impossible with PMF?
-
IMHO, as a general rule, it's safe to use PMF syntax in applications.
The difference between "old" and "new" style kicks in when cascaded destruction takes place, and a signal is delivered to a stale object. In the Qt library, this happens (amongst others) to slots in private headers.You can have a look at https://codereview.qt-project.org/c/qt/qtbase/+/507788 for instance.
Just replacing string based connections with PMF syntax lead to crashes, when the model of a combo box would still emit signals to the box's private header when it was already destroyed.QMetaObject
deals with this automatically, because it knows to which class the connection belongs. A PMF connection doesn't know when the slot object's d'tor is reached, so it needs to be explicitly disconnected. Otherwise a signal could be delivered toQComboBoxPrivate
when it has already degraded to a plainQObjectPrivate
. -
@Axel-Spoerl said in SIGNAL/SLOT() macros in Qt's source code:
A PMF connection doesn't know when the slot object's d'tor is reached, so it needs to be explicitly disconnected.
Whaatt?! In user code (as opposed to whatever private inside Qt for its own purposes)?? I only use PMF, I have never had a problem, I am expecting it to deal with either signal or slot object being destroyed without my having to do anything. I suppose I may never have tested a slot object deletion, not sure...
-
Whaatt?!
I guess you will never experience any issue with PMF based connections, unless you start plumbing with private classes created next to your public ones, go for multiple inheritance cascades and complex destruction with signals emitted to private headers.
I don't want to create any panic, I am just answering the question why we don't simply remove all string based connections in our code. -
@SimonSchroeder said in SIGNAL/SLOT() macros in Qt's source code:
What are things you can to with the string-based syntax that is impossible with PMF?
What @Christian-Ehrlicher said here
and here
That's (one of ) the reason(s) why the String-based syntax is still used with Qt's pImpl implementation and for "private slots".
AFAIK the PMF can connect to non slot-declared functions, but only within QObject-derived classes.
The string-based connection does not need QObject receiver. -
@Pl45m4 said in SIGNAL/SLOT() macros in Qt's source code:
The string-based connection does not need QObject receiver.
The signature is
QObject::connect(const QObject *, const char *, const QObject *, const char *, Qt::ConnectionType )
though -
@GrecKo said in SIGNAL/SLOT() macros in Qt's source code:
@Pl45m4 said in SIGNAL/SLOT() macros in Qt's source code:
The string-based connection does not need QObject receiver.
The signature is
QObject::connect(const QObject *, const char *, const QObject *, const char *, Qt::ConnectionType )
thoughThis was referring to this overload:
QMetaObject::Connection QObject::connect(const QObject *sender, const char *signal, const char *method, Qt::ConnectionType type = Qt::AutoConnection) const
Which implies that the target is the current object.
This is different from the similar (yet different) PMF variant as there's no implicit target in that case. Hence the recommendation to use the variant which has a context object.