Search code examples
c++qtqt-signals

Qt is it possible to define a function pointer in place of a signal?


I have a lot of signals which all have the same parameters but perform different functions.

The connect and disconnect code for all the signals will be the same, as is the slot handler that the signals connect to.

Instead of writing this code over and over. I would like to use a function pointer or something similar to assign to the signal, then have a common code block which performs the connection or disconnection.

The following code is just to illustrate what I am describing, it isn't valid and will not compile.

    void (*pfnSignal)(quint8, QString);
    switch( eSigID ) {
    case SIGNAL_A:
        pfnSignal = signalA; 
        break;
    case SIGNAL_B:
        pfnSignal = signalB;
        break;
    default:
        pfnSignal = NULL;           
    }
    if ( pfnSignal != NULL ) {
      QObject::connect(pobjRef, pfnSignal, this, SLOT(handler(quint8, QString)));
    }

Solution

  • In Qt5, this can be done easily, as it allows connecting using a new pointer to member function syntax.

    // Using decltype to avoid figuring out the ugly pointer-to-member-function syntax. 
    // Assumes all signals have the same arguments.    
    decltype<&ThatClass::someSignal> pfnSignal = nullptr;
    switch( eSigID ) {
    case SIGNAL_A:
        pfnSignal = &ThatClass::signalA; 
        break;
    case SIGNAL_B:
        pfnSignal = &ThatClass::signalB;
        break;          
    }
    
    if (pfnSignal) {
        connect(pobjRef, pfnSignal, this, &ThisClass::handler);
    }
    

    But actually, this is even possible with Qt4, as the SIGNAL macro is of type const char*.

    const char *pfnSignal = nullptr;
    switch( eSigID ) {
    case SIGNAL_A:
        pfnSignal = SIGNAL(signalA(quint8, QString)); 
        break;
    case SIGNAL_B:
        pfnSignal = SIGNAL(signalB(quint8, QString)); 
        break;         
    }
    if (pfnSignal) {
      QObject::connect(pobjRef, pfnSignal, this, SLOT(handler(quint8, QString)));
    }