3

众所周知,继承的信号不能用作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;
};

有没有更好/更优雅的解决方案来做到这一点?

4

1 回答 1

2

您可以做的一件事是阻止某人显式使用此信号,将其声明为私有,但 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 )

于 2016-06-26T21:02:49.977 回答