2016-06-26 20 views
3

Es ist bekannt, dass ein geerbtes Signal nicht als Q_PROPERTYNOTIFY er (https://bugreports.qt.io/browse/QTBUG-7684) verwendet werden kann. Als Workaround verwende ich ein zusätzliches Signal in der abgeleiteten Klasse, das ausgelöst wird, wenn das Basissignal ausgelöst wird. Die Basisklasse:Umgehung zu Q_PROPERTY NOTIFY mit geerbtem Signal

class Base : public QObject { 
    Q_OBJECT 

signals: 
    void mySignal(); 
}; 

für die abgeleitete Klasse:

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

Gibt es eine bessere/elegantere Lösung, dies zu tun?

+1

Was passiert, wenn Sie nur das Signal neu deklarieren? – peppe

Antwort

1

Eine Sache, die Sie tun können, um zu verhindern, dass jemand dieses Signal explizit verwendet, besteht darin, es als privat zu deklarieren, außer für den moc-run. Auf diese Weise niemand das Signal verwenden können:

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

Eine weitere Option, je nachdem, wie Sie Base verwenden, wäre ein reines virtuelles Signal zu verwenden:

class Base : public QObject { 
    Q_OBJECT 

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

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

ACHTUNG: Signale sind nicht virtuell. Sie können ein Signal nicht überschreiben. Es ist jedoch möglich, zu implementieren. Deshalb benutze ich das Finale hier, um zu verhindern, dass man es überschreibt. Der Code wird eine entsprechende Warnung generieren, aber solange Sie sich dessen bewusst sind, funktioniert es ordnungsgemäß.

Bitte beachten Sie, dass ich nicht ausprobiert habe, ob ein reines virtuelles Signal funktioniert, wenn die Basisklasse das Makro Q_OBJECT hat! es funktioniert, wenn Ihre Basisklasse wie eine Plugin-Schnittstelle deklariert ist (wie hier: https://doc.qt.io/qt-5/qtwidgets-tools-echoplugin-example.html#echointerface-class-definition)