Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
446 views
in Technique[技术] by (71.8m points)

c++ - Connect QML signal to C++11 lambda slot (Qt 5)

Connecting a QML signal to a regular C++ slot is easy:

// QML
Rectangle { signal foo(); }

// C++ old-style
QObject::connect(some_qml_container, SIGNAL(foo()), some_qobject, SLOT(fooSlot()); // works!

However, no matter what I try, I cannot seem to be able to connect to a C++11 lambda function slot.

// C++11
QObject::connect(some_qml_container, SIGNAL(foo()), [=]() { /* response */ }); // fails...
QObject::connect(some_qml_container, "foo()", [=]() { /* response */ }); // fails...

Both attempts fail with a function signature error (no QObject::connect overload can accept these parameters). However, the Qt 5 documentation implies that this should be possible.

Unfortunately, Qt 5 examples always connect a C++ signal to a C++ lambda slot:

// C++11
QObject::connect(some_qml_container, &QMLContainer::foo, [=]() { /* response */ }); // works!

This syntax cannot work for a QML signal, as the QMLContainer::foo signature is not known at compile-time (and declaring QMLContainer::foo by hand defeats the purpose of using QML in the first place.)

Is what I'm trying to do possible? If so, what is the correct syntax for the QObject::connect call?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Lambdas etc only work with new syntax. If you can't find a way to give QML signal as a pointer, then I think it is not directly possible.

If so, you have a workaround: create a dummy signal-routing QObject subclass, which only has signals, one for every QML signal you need to route. Then connect QML signals to corresponding signals of an instance of this dummy class, using the old connect syntax.

Now you have C++ signals you can use with the new syntax, and connect to lambdas.

The class could also have a helper method, to automate connections from QML to signals of the class, which would utilize QMetaObject reflection mechanisms and a suitable signal naming scheme, using same principle as QMetaObject::connectSlotsByName uses. Alternatively you can just hard-code the QML-router signal connections but still hide them inside a method of the router class.

Untested...


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...