【问题标题】:Qt: Is emitting signals in lamdas ok or it is bad style (and will it cause problems)Qt:在 lamdas 中发出信号正常还是风格不好(会导致问题)
【发布时间】:2019-09-21 18:51:56
【问题描述】:

假设我有一个包含ButtonSpinbox 的小部件。单击按钮时,我希望发出 Spinbox 的值。

我看到了两种可能的方法:
我可以创建一个私有成员函数

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

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

或者我可以直接在 lambda 中执行此操作:

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

lambda 方式看起来更整洁(因为我不需要创建一个相当空的成员函数),但另一方面,看到 lambda 中的 emit 让我有一种不好的感觉。

那么,是在 lambda 中发出信号好吗(我的直觉过于敏感),还是它的风格不好(或者我什至会为将来遇到一些意想不到的麻烦做好准备)

【问题讨论】:

    标签: qt c++11 lambda


    【解决方案1】:

    没关系

    emit 是一个空宏。信号是一个(工具生成的)函数,它的调用方式与任何其他函数相同。您已捕获 this,因此您可以从 lambda 调用任何成员,就好像您在 SomeWidget 方法中一样。

    【讨论】:

      【解决方案2】:

      完全没问题。但是,您的代码有问题:

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

      必须是:

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

      您必须为仿函数指定对象上下文,以确保在对象不再存在时不会调用仿函数。

      请参阅此post 了解更多信息。

      【讨论】:

      • 鉴于源是小部件拥有的按钮,连接的生命周期受小部件生命周期的限制
      • @Caleth 是的。不过,请记住,如果 lambda 的 this 指针的生命周期没有(安全地)与发送者的生命周期相关联。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-16
      • 2010-11-18
      • 1970-01-01
      • 1970-01-01
      • 2010-10-20
      • 1970-01-01
      相关资源
      最近更新 更多