How to replace `connect(this, SIGNAL(frameSwapped())...` with modern version
-
@ankou29666
As I wrote:- There are 3 methods, all on that page.
- Only one is marked as
slot
. But so what? I previously said:
BTW, the fact that only one is marked as
[slot]
does not affect the fact that you must specify which one for theconnect()
.That's why I wrote it :)
-
@JonB ok I hadn't read your previous answer properly. And your last one gets me even more confused. And wondering then what's the point in declaring slots ... if you have to tell explicitly to which slot to connect ... when there's only one declared ...
Can a signal be connected to a method not declared as slot with the new syntax ? That's what I first understood from your last answer but I then had some doubts ... But when I think about it, it can connect to a lambda function which is not declared slot either ... I'm getting a little lost ...
-
@ankou29666
Don't panic! You may be overthinking :)I never used the old-style
connect()
with strings/SIGNAL
/SLOT()
macros. So I cannot say whether they insisted on the slot function being marked withslot
.Yes, with the new syntax at least you can
connect()
to any method/function, even if it has not been declared in theslots
section. I don't know if there are any cases where it has to be marked as aslot
, but certainly in the normal case it does not matter. Python/PyQt might require a slot method to be@Slot
decorated, not sure, but C++/moc does not. Of course it is good practice to put slots into the class'sslots:
section, but you don't have to.I think the same is not true of signals. You do have to put signals into the
signals:
section, IIRC.The OP's original error message reads
error: no matching function for call to 'Window::connect(Window*, void (QOpenGLWindow::*)(), Window*, <unresolved overloaded function type>)' connect(this, &QOpenGLWindow::frameSwapped, this, &QOpenGLWindow::update);
Now, this is a C++ compiler error message. Whatever moc might or might not have done you can see the line being presented for compilation. It has to find a match, in a parameter to
connect()
, for&QOpenGLWindow::update
, that's all it sees. And that is ambiguous because there are 3 public methods ofQOpenGlWindow::update(...)
which are candidates. Whether one is or is not declared insideslots:
simply has no bearing. You need to tell it which one.The OP will need
connect(this, &QOpenGLWindow::frameSwapped, this, qOverload<>(&QOpenGLWindow::update));
Any parameters are specified inside the
<>
. Here that is empty so it matches the overload which takes no parameters.In the case of the old-style code it was the
SLOT(update())
which told it to pick theupdate()
method with no parameters. Had you wished to pick one which did take parameters you would have had to specify them inside theupdate(...)
. So both ways are effectively specifying the same information, just in different formats. -
@ankou29666 said in How to replace `connect(this, SIGNAL(frameSwapped())...` with modern version:
Can a signal be connected to a method not declared as slot with the new syntax ?
Yes
"what's the point in declaring slots" - it's just a hint for developers. Any method of a class can be a slot.
-
Ok I had started Qt by the times of 4.4 or so. New syntax didn't exist then. And then I didn't do any C++ until very recently. and with the old syntax it is required for a slot to be declared as such. That's what got me so troubled.
And this explains why the old syntax works when the new doesn't.I was rather expecting the connection to be automatically matched by determining the number and types of the arguments but this is obviously not the case.
-
@ankou29666 said in How to replace `connect(this, SIGNAL(frameSwapped())...` with modern version:
And wondering then what's the point in declaring slots
The old syntax used SIGNAL/SLOT macros to replace the functions with strings. Back then slots needed to be marked as slots because moc would only create mappings from the string to the function pointer for those methods. With the new syntax we are now using function pointers directly. So, for the connect call we don't have to qualify them as slots anymore. However, Qt also has some reflection built in. In these cases it could still make sense to declare some methods as slots. Though, to be honest, I haven't used that functionality in years...
-
@jeremy_k said in How to replace `connect(this, SIGNAL(frameSwapped())...` with modern version:
but suspect PyQt and PySide/Qt for Python do as well
I do not know how they implement "under the hood", but at least from a user perspective PyQt/PySide use a connection syntax "equivalent" to the new C++ style, referring to functions directly not through strings:
signallingObject.signal.connect(slotObject.slot) self.pushbutton.clicked.connect(self.onClicked)
-
@JonB said in How to replace `connect(this, SIGNAL(frameSwapped())...` with modern version:
@jeremy_k said in How to replace `connect(this, SIGNAL(frameSwapped())...` with modern version:
but suspect PyQt and PySide/Qt for Python do as well
I do not know how they implement "under the hood", but at least from a user perspective PyQt/PySide use a connection syntax "equivalent" to the new C++ style, referring to functions directly not through strings:
signallingObject.signal.connect(slotObject.slot) self.pushbutton.clicked.connect(self.onClicked)
Under the hood is what I was referring to. The python syntax isn't (IMHO of course) relevant to a question about a C++ implementation. The availability of the interface is.
Drifting off topic, I don't consider the python syntax equivalent to C++ function pointers. Detection of a nonexistant signal or slot doesn't happen until the initial runtime parse, and detection of incompatible arguments in the slot is delayed until slot invocation. For example:
... object = QObject() object.destroyed.connect(lambda x, y, z: print("QObject.destroyed() does not have 3 arguments")) print("No exceptions so far") del object # With PyQt: TypeError: <lambda>() missing 2 required positional arguments: 'y' and 'z'
-
@jeremy_k said in How to replace `connect(this, SIGNAL(frameSwapped())...` with modern version:
Detection of a nonexistant signal or slot doesn't happen until the initial runtime parse, and detection of incompatible arguments in the slot is delayed until slot invocation.
Which is how Python works compared against C++, regardless of Qt.
My comment about Python signal connections was just intended as an observation, about how it works at coding time using function (or whatever) calls rather than strings. User gets a language check that signal and slot functions exists (at runtime in Python, and hopefully something at editing time too).
-
@JonB said in How to replace `connect(this, SIGNAL(frameSwapped())...` with modern version:
@jeremy_k said in How to replace `connect(this, SIGNAL(frameSwapped())...` with modern version:
Detection of a nonexistant signal or slot doesn't happen until the initial runtime parse, and detection of incompatible arguments in the slot is delayed until slot invocation.
Which is how Python works compared against C++, regardless of Qt.
I agree. This is more like the string based connect.
My comment about Python signal connections was just intended as an observation, about how it works at coding time using function (or whatever) calls rather than strings. User gets a language check that signal and slot functions exists (at runtime in Python, and hopefully something at editing time too).
That's an IDE feature. My browser tells me when things that I type in a text input aren't in its dictionary. The words are still more like free strings than function pointers.