Qt连接Lambda不工作

时间:2013-12-11 03:38:36

标签: c++ qt lambda

我一直在尝试使用Qt中的新Lambda插槽,但由于某些原因我似乎无法使用这个插槽。以下是代码失败的相关部分:

QAction exitApplicationAction("Quit", nullptr);

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

是否有人发现此代码存在问题?错误消息是:

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

我真的坚持这个。

2 个答案:

答案 0 :(得分:3)

更新: 这是您尝试引用的QObject::connect调用的重载,以及根据您提供的参数无法找到的错误:

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

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

您的参数分配中包含:

const QObject * sender = &exitApplicationAction

以上传递作为正确的参数,但是一旦离开当前范围,它将成为一个错误的指针,并导致运行时崩溃。相反,分配到堆上,并正确使用父级。但这不适用于您提供的其他参数......请继续阅读。

PointerToMemberFunction signal = &QSystemTrayIcon::activated

您的QObject *发件人不是QSystemTrayIcon,而是QAction *。因此,它不是连接的有效信号。如果要连接到QSystemTrayIcon的激活信号,则必须将QSystemTrayIcon指针作为第一个参数传递。

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

这个仿函数看起来可以工作。如果它看起来不起作用,请仔细检查lambda示例。

UPDATE结束。

这与Qt 5中支持的新lambda语法有关,如果您的编译器支持它。

  

新:连接简单功能

     

新语法甚至可以连接到函数,而不仅仅是QObjects:

     

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

     

     

可与tr1::bind

一起使用      

可以与c ++ 11 lambda表达式一起使用

     

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

     

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

     

缺点

     

“接收器”被销毁时没有自动断开连接

在维基页面上,它提供了一些如何使用lambda功能的示例:

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

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

如果您查看MSDN,Lambda语法有很多内容:

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

c ++的所有支持选项,返回值,变量范围,变量引用等都有点复杂。所以现在找一个关闭的例子应该可以工作。

但正如上面的评论所说,可能有更好的方法来做到这一点。

而是将QAction实例化为主窗口小部件或QMainWindow内的指针,并将其连接到该窗口的关闭事件槽。像这样:

// 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

希望有所帮助。

答案 1 :(得分:1)

真正的问题是我试图从QAction获取 QSystemTrayIcon 信号。这将有效:

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

关键是你使用& QAction :: triggered 而不是 & QSystemTrayIcon :: activated