C++ – How to use QMetaMethod with QObject::connect

cqtqt4

I have two instances of QObject subclasses and two QMetaMethod instances of signal in one of objects and slot in another object. I want to connect this signal and slot with each other.

I've looked through the qobject.h file and find that SIGNAL() and SLOT() macro are just add "1" or "2" character to the beginning of method signature so it looks like it should be possible to add the same character to the beginning of string returned by QMetaMethod::signature() but this approach depends on some undocumented internals of toolkit and may be broken at any time by a new version of Qt.

Does anybody know reliable way to connect signals and slots through their QMetaMethod reflection representation?

Edited:
I've created suggestion in Qt issue tracker:
https://bugreports.qt.io/browse/QTBUG-10637
If anybody also interested in this feature you can vote for this ticket there.

Best Answer

This has been fixed as of Qt 4.8.0:

https://bugreports.qt.io/browse/QTBUG-10637

Suppose we have a QObject* m_subject, and wish to connect the change-notification signal of a property to a propertyChanged() slot:

const QMetaObject* meta = m_subject->metaObject();
QMetaProperty prop = meta->property(meta->indexOfProperty("myProperty"));
if (prop.hasNotifySignal()) {
    QMetaMethod signal = prop.notifySignal();
    QMetaMethod updateSlot = metaObject()->method(
        metaObject()->indexOfSlot("propertyChanged()"));
    connect(m_subject, signal, this, updateSlot);
}

I successfully used this to make a QWidget subclass which finds all the properties of any QObject and creates a QLineEdit for each of them, with a connection to keep the QLineEdit updated whenever the corresponding property changes. (Because I didn't find a way to pass a propertyID value to propertyChanged() though, it was necessary to make a subclass of QLineEdit and implement propertyChanged() there. QSignalMapper didn't help, because all the properties are in the same object.)