3

I have been experimenting with the new Lambda slots in Qt, and I can't seem to get this one to work for some reason. Here's the relevant parts of the code that is failing:

QAction exitApplicationAction("Quit", nullptr);

QObject::connect(&exitApplicationAction, &QSystemTrayIcon::activated, [&](QSystemTrayIcon::ActivationReason activationReason)
{
    qApp->quit();
});

Does anybody see a problem with this code? The error message is:

error: C2665: 'QObject::connect' : none of the 4 overloads could convert all the argument types

I'm really stuck on this one.

2
  • qt-project.org/doc/qt-4.8/qobject.html#connect-3 this doc says that you are supposed to provide 4 arguments. I also can't see a real use for a lambda here or for a function object in general. Commented Dec 11, 2013 at 3:47
  • I had a similar problem: The problem was a class mismatch in the first 2 parameters and not the lambda. Your problem helped me see it. Commented Aug 23, 2016 at 18:23

2 Answers 2

2

UPDATE: This is the overload of the QObject::connect call that you are trying to refer to, and what your error is says it can't find based on the parameters you give it:

http://doc-snapshot.qt-project.org/qdoc/qobject.html#connect-5

QMetaObject::Connection QObject::connect(
    const QObject * sender, 
    PointerToMemberFunction signal, 
    Functor functor) [static]

You have in your parameter assignments:

const QObject * sender = &exitApplicationAction

The above passes as the correct parameter, but as soon as you leave your current scope it will become a bad pointer, and cause a runtime crash. Instead, allocate onto the heap, and use parenting correctly. But this doesn't work with your other parameters you give it... read on.

PointerToMemberFunction signal = &QSystemTrayIcon::activated

Your QObject * sender is not a QSystemTrayIcon, it is a QAction *. Therefore it is not a valid signal to connect to. If you want to connect to the activation signal of the QSystemTrayIcon, you have to pass the QSystemTrayIcon pointer as the first parameter.

Functor functor = [&](QSystemTrayIcon::ActivationReason activationReason) { qApp->quit();}

This functor looks like it could work. Double check the lambda examples if it doesn't seem to work.

End of UPDATE.

This relates to the new lambda syntax supported in Qt 5, and if your compiler supports it.

New: connecting to simple function

The new syntax can even connect to functions, not just QObjects:

connect(sender, &Sender::valueChanged, someFunction);

pro

can be used with tr1::bind

can be used with c++11 lambda expressions

connect(sender, &Sender::valueChanged, tr1::bind(receiver, &Receiver::updateValue, "senderValue", tr1::placeholder::_1) );

connect(sender, &Sender::valueChanged, [=](const QString &newValue) { receiver->updateValue("senderValue", newValue); } );

cons

There is no automatic disconnection when the ‘receiver’ is destroyed

On the wiki page it gives a few examples of how to use the lambda functionality:

http://qt-project.org/wiki/New_Signal_Slot_Syntax

http://qt-project.org/wiki/New_Signal_Slot_Syntax#45f5369b0d8445adbaf54cd74a36b823

And if you check out MSDN there is quite a bit on the Lambda syntax:

http://msdn.microsoft.com/en-us/library/dd293603.aspx

It gets a little complex with all the supported options of c++, return values, scoping of variables, variable references, etc. So for now finding an example that is close should work.

But like was said in the comments above, there is probably a better way to do this.

Instead instantiate the QAction as a pointer inside your main widget or QMainWindow, and connect it to the close event slot of that window. Like so:

// somewhere in your constructor

QAction * action = new QAction("Quit", this);
QObject::connect(action, SIGNAL(triggered()), this, SLOT(close()));

// And make sure you add the action to a menu or a button or a toolbar, too

Hope that helps.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the help! However, this wasn't the problem. It was actually trying to get signals from the system tray icon when working with an action. I think you pointed that out though!
0

The real problem was that I was trying to get a QSystemTrayIcon signal from a QAction. This will work:

QObject::connect(&exitApplicationAction, &QAction::triggered, qApp, &QApplication::quit);

The key is that you use the &QAction::triggered, not the &QSystemTrayIcon::activated.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.