Utilizing connect with the SIGNAL macro and a functor



  • Hello,

    I'm trying to dynamically connect a widget to a functor. I have a file that contains the signature of the signal that I want to connect, as well as some info concerning what it should do, something along the line of:

    "widget": "power_button",
    "signal": "toggled(bool)",
    "action": "power"

    As you can see, the signal is easy to connect, I can just call connect with the string (I just have to prepend a "2" and convert to const char*). I can't (at least easily) use the pointer-to-member syntax easily because those widgets are created at runtime and they don't have all the same signals (and signal signatures).

    So I would like to be able to call something like

    QObject::connect(widget, signal_string, [](bool a){ set("power", a); });
    

    but there is no connect overload like that, and I'm afraid the two syntaxes are fundamentally incompatible.

    Is there a way to do what I want, or will I have to do something a bit more complicated ?

    Thnaks a lot !


  • Lifetime Qt Champion

    Hi and welcome to the forums.
    Sadly, macro syntax and lambdas cannot be mixed.
    https://wiki.qt.io/New_Signal_Slot_Syntax
    So I guess you are looking at something "bit more complicated "


  • Moderators

    @VanDriekenof
    i once wrote an utility class for this

    #include <functional>
    
    typedef std::function<void()> LamdbaFunc;
    
    class LambdaConnector : public QObject
    {
        Q_OBJECT
    
    public:
        LambdaConnector( QObject* obj, const char* signal, LambdaFunc functor ) : QObject(obj) {
            static QMetaMethod slotMethod;
            if( !slotMethod.isValid() )
            {
                    const QMetaObject * mo = this->metaObject();
                    int idx = mo->indexOfSlot("onEmit()");
                    slotMethod = mo->method(idx);
            }
    
            QMetaMethod signalMethod = obj->metaObject()->method(obj->metaObject()->indexOfSignal(signal));
            connect( object, signalMethod, this, slotMethod );
       }
    
    private slots:
        void onEmit() {
           m_SlotFunction();
       }
    
    private:
        LambdaFunc m_SlotFunction;
    };
    

    Usage:

    new LambdaConnector(obj, "signal()", [obj]() {
        obj->...
    });
    // or
    new LambdaConnector(obj, QMetaObject::normalizedType("signal()").constData(), [obj]() {
        obj->...
    });
    

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.