Page MenuHomePhabricator

Use new Qt5 signal-slot syntax
Closed, WontfixPublic

Description

A new signal-slot syntax has been added to Qt5 years ago.
We still have a lot of old-style connect calls. This task should be used to discuss if and how it can be managed to switch to the new signal-slot syntax.

For more information, see:

Event Timeline

kalali triaged this task as Wishlist priority.Mar 6 2020, 6:55 PM
kalali created this task.

Note that this is an alternative syntax, not a successor. For example, you can't use the new syntax for overloaded signals like valueChanged(int/double) of QSpinBox, or to be precise, it is possible but super ugly, verbose and multi-line. So I wouldn't recommend to systematically change everything to the modern C++ syntax but I think it is worth it to take lambdas into account which could result in the removal of quite some short slots that otherwiese are boilerplate with there declaration and definition compared to a single-line lambda.

, it is possible but super ugly, verbose and multi-line.

That's a bit extrem. I wouldn't call the following statement super multiline or verbose:

connect(mySpinBox,  QtOverload<int>::of(&QSpinBox::valueChanged), this, &MyClass::OnChange);

And thats all you need. But I agree that not every connect should dumbly beeing converted. But I think in most cases it would increase the stability of our code base as it moves runtime errors to compile time errors.

P.S.: Overloaded signals are also discouraged in nowadays be the Qt developers.

That's a bit extrem. I wouldn't call the following statement super multiline or verbose:

connect(mySpinBox,  QtOverload<int>::of(&QSpinBox::valueChanged), this, &MyClass::OnChange);

Nice, I didn't know about QtOverload. ๐Ÿ‘
I was referring to the "old new" way:

void (QSpinBox::* mySignal)(int) = &QSpinBox::valueChanged;
connect(mySpinBox, mySignal, mySlider, &QSlider::setValue);
void (QSpinBox::* mySignal)(int) = &QSpinBox::valueChanged;
connect(mySpinBox, mySignal, mySlider, &QSlider::setValue);

Ok, that IS super super ugly, multiline and verbose. I give you that. ;)

But I think in most cases it would increase the stability of our code base as it moves runtime errors to compile time errors.

That's exactly my number one reason why I proposed to discuss this syntax.
Another one is that it allows to use slots that were originally not designed to be slots (e.g. of non-Q_OBJECT-classes).
Third point (that is something we had with our selection-refactoring and did not detect it immediately (because of runtime error instead of compile time errors)): It handles typedefs and namespaces!

Also, concerning the super ugly version, I did this sometimes (although I'd prefer the QtOverload-way):

connect(mySpinBox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), mySlider, &QSlider::setValue);

Also, concerning the super ugly version, I did this sometimes (although I'd prefer the QtOverload-way):

connect(mySpinBox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), mySlider, &QSlider::setValue);

Quoting from the first article you linked in the task description: "Unfortunately, using an explicit cast here allows several types of errors to slip past the compiler. Adding a temporary variable assignment preserves these compile-time checks".

Oh, good to know. So QtOverload it is, I guess?

The recommended way of using QtOverload seems to be via macros in C++14 (our minimum C++ standard). There are also macros for const overloads and explicitly non-const overloads:
https://doc.qt.io/qt-5/qtglobal.html#qOverload

Here are all four (five) variants mentioned and the explicit cast is used as an alternative as well:
https://doc.qt.io/qt-5/signalsandslots-syntaxes.html#selecting-overloaded-signals-and-slots

kislinsk added a project: Auto-closed.

Hi there! ๐Ÿ™‚

This task was auto-closed according to our Task Lifecycle Management.
Please follow this link for more information and don't forget that you are encouraged to reasonable re-open tasks to revive them. ๐Ÿš‘

Best wishes,
The MITK devs