connect and disconnect lambda

In Qt, connecting a signal to a slot is done as follows:

connect(sender,signal,receiver,slot);

This is a static function of QObject. QObject has also non-static versions of connect so you can connect signal to slot as follows:

receiver->connect(sender,signal,slot);

Of course, receiver must be an object of some class derived of QObject.

Things go pretty much well until the introduction of lambda expression in recent Qt versions. Now you can connect a signal to a lambda expression:

connect(sender,signal,lambda);

The lambda expression has a weird syntax and if you see it at the first time you may get confused.

connect(view, &QWebEngineView::loadFinished, [this](bool success) { QMessageBox::information(this,"ok","load finished");});

You can see the lambda is somewhat like an anonymous function: it has parameter(s) in () and it has code block in {}. But what is the stuff in []? Well, they are the variables you can use in the code block, in this case, “this”, i.e. the current object, can be used in the code block. The introduction of lambda expression makes it smoother to provide a slot that handles a signal.
You can connect multiple lambdas to the same signal of the same sender:

connect(view, &QWebEngineView::loadFinished, [this](bool success) { QMessageBox::information(this,"ok","lambda1");});
connect(view, &QWebEngineView::loadFinished, [this](bool success) { QMessageBox::information(this,"ok","lambda2");});

When the signal is emitted, all the lambdas are called in the order of connection. In this case, the message box “lambda1″ is displayed then the message box “lambda2″ is displayed.
Now the problem arises: how to disconnect a specific lambda from the signal? Of course you can disconnect all the lambdas as follows:

disconnect(view, &QWebEngineView::loadFinished);

But if you just want to disconnect the first lambda from the signal, how to do that? Just copying the first connect code and replacing connect with disconnect does not work(syntax error). You should “remember” the connection when you create it in order to disconnect it later:

QMetaObject::Connection conn;
std::unique_ptr pconn{new QMetaObject::Connection};
conn = *pconn;
conn=connect(view, &QWebEngineView::loadFinished, [this](bool success) { QMessageBox::information(this,"ok","lambda1");});
disconnect(conn);

Reference:https://stackoverflow.com/questions/14828678/disconnecting-lambda-functions-in-qt5

Posted in

Comments are closed, but trackbacks and pingbacks are open.