Обходной путь для Q_PROPERTY NOTIFY с унаследованным сигналом

Известно, что унаследованный сигнал нельзя использовать в качестве Q_PROPERTY NOTIFYer (https://bugreports.qt.io/browse/QTBUG-7684). В качестве обходного пути я использую дополнительный сигнал в производном классе, который срабатывает при срабатывании базового сигнала. Базовый класс:

class Base : public QObject {
    Q_OBJECT

signals:
    void mySignal();
};

Для производного класса:

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;
};

Есть ли лучшее/более элегантное решение для этого?


person Ayberk Özgür    schedule 26.06.2016    source источник
comment
Что произойдет, если вы просто повторно объявите сигнал?   -  person peppe    schedule 26.06.2016


Ответы (1)


Одна вещь, которую вы можете сделать, чтобы предотвратить явное использование этого сигнала, — это объявить его закрытым, за исключением moc-run. Таким образом, никто не может использовать сигнал:

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

Другим вариантом, в зависимости от того, как вы используете Base, будет использование чистого виртуального сигнала:

class Base : public QObject {
    Q_OBJECT

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

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

ВНИМАНИЕ: сигналы не являются виртуальными. Вы не можете отменить сигнал. Однако реализовать это возможно. Вот почему я использую здесь final, чтобы предотвратить его перезапись. Код выдаст соответствующее предупреждение, но пока вы знаете об этом факте, он работает правильно.

Обратите внимание, что я не пробовал, работает ли чистый виртуальный сигнал, если в базовом классе есть макрос Q_OBJECT! это работает, если ваш базовый класс объявлен как интерфейс плагина (как здесь: https://doc.qt.io/qt-5/qtwidgets-tools-echoplugin-example.html#echointerface-class-definition)

person Felix    schedule 26.06.2016