3

Let's say I have Widget containing a Button and a Spinbox. When the Button is clicked I wish to emit the value of the Spinbox.

I see two possible ways to do this:
Either I can create a private member function

//...
connect(m_Button, &QPushButton::clicked, this, &SomeWidget::emitSpinboxValue);
//...

SomeWidget::emitSpinboxValue() {
    emit spinboxValueChanged(m_Spinbox->value());
}

Or I can directly do that in a lambda:

//...
connect(m_Button, &QPushButton::clicked, [this]() { emit spinboxValueChanged(m_Spinbox->value()) });
//...

The lambda way looks neater (since I do not need to create a rather empty member function), but on the other hand seeing that emit in the lambda gives me a bad feeling in my gut.

So, is emitting signals in a lambda ok (and my gut oversensitive), or is it bad style (or do I even set myself up for some unexpected trouble in the future)

CharonX
  • 2,130
  • 11
  • 33

2 Answers2

4

It's fine

emit is an empty macro. A signal is a (tool generated) function, and it gets called in the same way as any other function. You've captured this, so you can call any member from the lambda as-if you were in a SomeWidget method.

Caleth
  • 52,200
  • 2
  • 44
  • 75
1

It is totally fine. However, there is something wrong in your code:

connect(m_Button, &QPushButton::clicked, [this]() { emit spinboxValueChanged(m_Spinbox->value()) });

Must be:

//                                    Important!
//                                       vvvv
connect(m_Button, &QPushButton::clicked, this, [this]() { 
    emit spinboxValueChanged(m_Spinbox->value()); 
});

You have to specify the object context for the functor to ensures that the functor will not get invoked if the object does not exist anymore.

See this post for more information.

mohabouje
  • 3,867
  • 2
  • 14
  • 28
  • Given that the source is a button owned by the widget, the connection's lifetime is bounded by the widget's lifetime – Caleth May 03 '19 at 10:54
  • @Caleth Yup. Still, it is a good thing to keep in mind if the lifetime of the `this` pointer of the lambda were not (safely) tied to the lifetime of the sender. – CharonX May 03 '19 at 12:31