【问题标题】:Workaround to Q_PROPERTY NOTIFY with inherited signal使用继承信号解决 Q_PROPERTY NOTIFY
【发布时间】:2016-10-28 14:34:01
【问题描述】:

已知继承信号不能用作Q_PROPERTYNOTIFYer (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;
};

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

【问题讨论】:

  • 如果你只是重新声明信号会发生什么?

标签: c++ qt inheritance signals qt5.6


【解决方案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

【讨论】:

    猜你喜欢
    • 2017-09-28
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    • 2012-08-14
    • 1970-01-01
    • 1970-01-01
    • 2017-11-03
    • 2017-09-18
    相关资源
    最近更新 更多