0

I have a function (public slot)

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

that is connected to signal of QCompleter as

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

The purpose of the above code is, whenever i use complete() function from QCompleter, the suggestions pop up on line edit and upon clicking a suggestion, that particular text should come on the line edit.

The above code works as I expect

Problem Since the function has only one statement I want to use lambda expression in the connect function itself. Thereby saving code length and Improving readibility. Upon googling I found this. Upon referring the site I wrote code like this

Try 1

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

But Qt is throwing the error

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

Try 2

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

But Qt threw error

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

What am I doing wrong?

Try3

As pointed in comments I also tried

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

Error I got

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

                                                                                    ^
halfer
  • 19,824
  • 17
  • 99
  • 186
Gurushant
  • 952
  • 6
  • 23
  • 1
    You should add `this` as the receiver of your lambda-slot, because otherwise the signal could execute the lambda et try to access `ui_add_new_part` even if your object has been destroyed, it is a good practice. – ymoreau Jun 21 '18 at 11:38
  • @G.M. I tried all the possible solutions from their, but it did not help – Gurushant Jun 21 '18 at 11:46
  • @ymoreau I tried [this, &] as well as [&, this] also tried [this] but did mot help either – Gurushant Jun 21 '18 at 11:47
  • @king_nak the answers have the almost same solution as first pointed by G.M – Gurushant Jun 21 '18 at 11:51
  • @guru I didn't mean to pass `this` in the lambda, but to use as receiver of the slot, in the connect function `connect(pointer, &Class::signal, this, [&](...` – ymoreau Jun 21 '18 at 12:04
  • 1
    1. It is `QOverload::of(...)` or `qOverload(...)`. 2. What Qt version do you use? 3. What compiler&version / C++ version do you use? – king_nak Jun 21 '18 at 13:21
  • @king_nak thanks that worked.. I am using Qt 5.10.1. Compiler mingw 5.3.0. C++ Version I think its default of Qt i.e C++11 – Gurushant Jun 22 '18 at 05:04

4 Answers4

3

That's because QCompleter has two overloads of activated. You need to specify which one you want to use:

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

It's in the docs, actually. Your Try 3 is missing ::of after QOverload<const QString &>.

Sergei Ousynin
  • 170
  • 2
  • 13
2

The way you use the new call syntax makes it ambiguous. Compare:

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

with

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

The type information about activated is missing, the compiler has to deduct it. The problem is: there are two overloads of that method:

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

With more advanced template machinery, the connect could be made to select overloads based on the types in the receiver side of the connection. But it's not implemented yet. That's why Qt provides QOverload and qOverload, so that you don't have to write awkward casts yourself. Allversions below are equivalent; the qOverload one is a bit less verbose but requires a newer compiler. The QOverload works on all compilers that current Qt supports.

connect(obj, QOverload<QString>::of(&Class::activated), ...)
connect(obj, qOverload<QString>(&Class::activated), ...)
connect(obj, static_cast<void(Class::*)(const QString&)>(&Class::activated), ...)
Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
0

Try to remove const from this part ( const QString &text )

0

Finally after lots of trial and error from the answers mentioned in comments, I was able to compile without errors and it worked

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

Thank you everyone

Edit: As stated in comments and others answers, i was missing "of" in try 3 Now this also works

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