3

It is known that an inherited signal cannot be used as a Q_PROPERTY NOTIFYer (https://bugreports.qt.io/browse/QTBUG-7684). As a workaround I'm using an extra signal in the derived class that gets fired when the base signal gets fired. The base class:

class Base : public QObject {
    Q_OBJECT

signals:
    void mySignal();
};

For the derived class:

class Derived : public Base {
    Q_OBJECT
    Q_PROPERTY(int myPropery READ getMyProperty NOTIFY mySignal_inherited)

public:
    Derived(){
        connect(this, SIGNAL(mySignal()), this, SIGNAL(mySignal_inherited()));
    }

    int getMyProperty(){ return myProperty; }

signals:
    void mySignal_inherited(); ///< DO NOT USE EXPLICITLY

private:
    int myProperty;
};

Is there a better/more elegant solution to do this?

Ayberk Özgür
  • 4,986
  • 4
  • 38
  • 58

1 Answers1

2

One thing you can do to prevent someone from explicitly using this signal is to declare it private, except for the moc-run. This way no one can use the signal:

signals:
#ifndef Q_MOC_RUN//this will be defined if moc runs, thus skipped
private:
#endif
    void mySignal_inherited(); ///< DO NOT USE EXPLICITLY

Another option, depending on how you are using Base, would be to use a pure virtual signal:

class Base : public QObject {
    Q_OBJECT

signals:
    virtual void mySignal() = 0;
};

class Derived : public Base {
    //...
signals:
    void mySignal() final;//mark as final
};

WARNING: Signals are not virtual. You cannot override a signal. However, implementing it is possible. Thats why I am using final here, to prevent one from overwriting it. The code will generate a corresponding warning, but as long as you are aware of that fact, it works properly.

Please note that I haven't tried out if a pure virtual signal works if the base-class has the Q_OBJECT macro! it does work, if your base class is declared like a plugin interface (Like here: https://doc.qt.io/qt-5/qtwidgets-tools-echoplugin-example.html#echointerface-class-definition)

Felix
  • 6,885
  • 1
  • 29
  • 54