【问题标题】:Why Qt is throwing error for lambda expression in signal and slot? [duplicate]为什么 Qt 在信号和槽中为 lambda 表达式抛出错误? [复制]
【发布时间】:2018-11-30 17:05:10
【问题描述】:

我有一个函数(公共槽)

void Parts::Testing(QString text)
{
    ui_add_new_part->lineEdit_InvoiceNumber->setText(text);
}

连接到 QCompleter 的信号为

connect(completer_part_invoice, SIGNAL(activated(QString)),
                    this, SLOT(Testing(QString)));

上述代码的目的是,每当我使用 QCompleter 中的 complete() 函数时,建议会在行编辑中弹出,并且在单击建议时,该特定文本应该出现在行编辑中。

上面的代码按我的预期工作

问题 由于该函数只有一个语句,我想在连接函数本身中使用 lambda 表达式。从而节省代码长度并提高可读性。 谷歌搜索后,我找到了this。在引用该网站后,我编写了这样的代码

试试 1

connect(
    completer_part_invoice, &QCompleter::activated,
    [&]( const QString &text )
    {
    ui_add_new_part->lineEdit_InvoiceNumber->setText(text);
});

但是 Qt 抛出错误

error: no matching function for call to 'Parts::connect(QCompleter*&, <unresolved overloaded function type>, Parts::pop_Up_Invoices()::<lambda(const QString&)>)'
             );
         ^

试试 2

connect(
    completer_part_invoice, SIGNAL(activated(QString)),
    [&]( const QString &text )
    {
    ui_add_new_part->lineEdit_InvoiceNumber->setText(text);
});

但是 Qt 抛出错误

error: no matching function for call to 'Parts::connect(QCompleter*&, const char [20], Parts::pop_Up_Invoices()::<lambda(const QString&)>)'
             });
              ^

我做错了什么?

Try3

正如我在 cmets 中指出的那样,我也尝试过

connect(
    completer_part_invoice, QOverload<const QString &>(&QCompleter::activated),
    [&](const QString &text)->void
    {
    ui_add_new_part->lineEdit_InvoiceNumber->setText(text);
});

我遇到的错误

 error: no matching function for call to 'QOverload<const QString&>::QOverload(<unresolved overloaded function type>)'
                 completer_part_invoice, QOverload<const QString &>(&QCompleter::activated), 

                                                                                    ^

【问题讨论】:

  • 你应该添加 this 作为你的 lambda-slot 的接收者,因为否则信号可能会执行 lambda 并且即使你的对象已经被销毁,也尝试访问 ui_add_new_part,这是一个很好的选择练习。
  • @G.M.我尝试了他们所有可能的解决方案,但没有帮助
  • @ymoreau 我试过 [this, &] 以及 [&, this] 也试过 [this] 但也没有帮助
  • @king_nak 答案与 G.M 首次指出的解决方案几乎相同
  • 1.它是QOverload&lt;T&gt;::of(...)qOverload&lt;T&gt;(...)。 2. 你用什么Qt版本? 3.你用什么编译器&版本/C++版本?

标签: c++ qt lambda


【解决方案1】:

这是因为QCompleter 有两个activated 重载。您需要指定要使用哪一个:

connect(completer_part_invoice, QOverload<const QString&>::of(&QCompleter::activated),
    this, [&](const QString& text) {
        ui_add_new_part->lineEdit_InvoiceNumber->setText(text);
});

实际上是in the docs。您的 Try 3QOverload&lt;const QString &amp;&gt; 之后缺少::of

【讨论】:

  • 哎呀,已经在 cmets 中了
【解决方案2】:

您使用新调用语法的方式使其模棱两可。比较:

connect(obj, SIGNAL(activated(QString)), ...)

connect(obj, &Class::activated, ...)

缺少activated的类型信息,编译器要扣除。问题是:该方法有两个重载:

void C::activated(const QString &text)
void C::activated(const QModelIndex &index)

使用更高级的模板机制,connect 可以根据连接接收方的类型来选择重载。但它还没有实施。这就是 Qt 提供QOverloadqOverload 的原因,这样您就不必自己编写笨拙的演员表。以下所有版本是等效的; qOverload 稍微不那么冗长,但需要更新的编译器。 QOverload 适用于当前 Qt 支持的所有编译器。

connect(obj, QOverload<QString>::of(&Class::activated), ...)
connect(obj, qOverload<QString>(&Class::activated), ...)
connect(obj, static_cast<void(Class::*)(const QString&)>(&Class::activated), ...)

【讨论】:

    【解决方案3】:

    尝试从这部分删除const(const QString &text)

    【讨论】:

    • 这并没有解决问题
    • @guru 也删除了 'text' 之前的这个符号 '&'
    • 我也试过了
    • 这只是个坏建议。 const QString &amp; 是您在 C++ 中传递任何重要值的方式。
    【解决方案4】:

    最后,在 cmets 中提到的答案中经过大量试验和错误后,我能够毫无错误地编译并且它工作了

            connect(
                completer_part_invoice, static_cast<void (QCompleter::*)(const QString&)>(&QCompleter::activated),
                [&](const QString &text)->void
                {
                ui_add_new_part->lineEdit_InvoiceNumber->setText(text);
            });
    

    谢谢大家

    编辑:如 cmets 和其他答案所述,我在尝试 3 中缺少“of” 现在这也有效

            connect(completer_part_invoice, 
                    QOverload<const QString&>::of(&QCompleter::activated),
                this, [&](const QString& text) {
                    ui_add_new_part->lineEdit_InvoiceNumber->setText(text);
            });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多