15

To connect signals to slots, as far as I know, the parameters of the signal need to match the parameters of the slot. So for example:

connect(dockWidget->titleBarWidget(), SIGNAL(closeButtonClicked()), ui->sideControls, SLOT(closeDockWidget()));

But what if I want to have a signal call a slot that has a different amount of parameters, but always pass a constant value into the slot. For example, using the above piece of code:

connect(dockWidget->titleBarWidget(), SIGNAL(closeButtonClicked()), ui->sideControls, SLOT(setDockWidget(false)));

Or in other words, whenever the button is pressed, it calls the setDockWidget() function with the false parameter. Is this possible?

Leif Andersen
  • 21,580
  • 20
  • 67
  • 100

3 Answers3

18

You can use lambda with desired call with constant argument. Example:

connect(obj, &ObjType::signalName, [this]() { desiredCall(constantArgument); });

More about new connect syntax: https://wiki.qt.io/New_Signal_Slot_Syntax.

BiTOk
  • 716
  • 1
  • 6
  • 15
  • In Your case is it possible to mix constant argument with variable? – Aleksey Kontsevich May 05 '16 at 22:05
  • @AlekseyKontsevich: If I understand you correctly, you want to pass a variable from the signal to the slot as well? Sure you can. Make it an argument to the lambda and use that argument in the function invocation. However, I do recommend you use the context argument with the value 'this' as well. This way, you can be sure the connection is destructed if the receiving object is destructed. Otherwise, you may end up in undefined behaviour. – André Jun 08 '16 at 10:35
9

No, it is not possible. You are only allowed to connect slots with less or equal argument count, than in corresponding signal. (see documentation)

You have to create proxy slot, that will call desired one.

Lol4t0
  • 12,444
  • 4
  • 29
  • 65
  • 1
    This answer is no longer really valid, as the Qt5 syntax on C++11 makes it quite easy to use a lambda for this purpose. – André Jun 08 '16 at 10:36
  • 1
    @André, On the other side, you just can `create proxy slot, that will call desired one.` now in place – Lol4t0 Jun 08 '16 at 15:04
  • 1
    Sure, you can. But an extra slot means more stuff in your header you don't want, exposing to outside calls (yes, even if a private slot can be called from the outside) and spreading around your code over multiple locations. You may even need additional member variables to contain values you want to pass, thus introducing additional state in your class. The lambda solution is so much more elegant that it disqualifies the introduction of a proxy slot as a solution IMO. – André Jun 08 '16 at 18:51
6

In a way, yes, you can. But it's not very powerful : just declare the setDockWidget this way :

[virtual] void setDockWidget(bool state=false) ;

And declare the connection this way :

connect(emitter, SIGNAL(closeButtonClicked()), receiver, SLOT(setDockWidget()));

setDockWidget called without arguments take the default ones.

azf
  • 2,179
  • 16
  • 22