如何覆盖 Q_Property?

How to override a Q_Property?

考虑这些 classes:

Class A : public QObject {
    ...
    Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged)

    virtual int value() { return m_value; }
    void setValue(int v) { m_value = v; Q_EMIT valueChanged();}
    ...

};

Class B : public A {
    ...

    int value() { return m_value * 2; }

    ...
};

访问属性值时,直接调用ClassA方法,而不是ClassB方法。

到目前为止,为了解决这个明显的限制,我已经复制了 属性 代码并连接了来自每个 class 的信号。

这是最好的解决方案吗?

有没有人看到潜在的问题(由于属性具有相同的名称)?

Q_PROPERTY ... // the same
signals:
    void valueChanged(int value);
public:
int value() const { return m_value; }
virtual void setValue(int newValue) { 
    m_value = newValue; 
    emit valueChanged( value() ); 
}


class B : public A {
public:
    void setValue(int newValue) { A::setValue(newValue *2); }
}

变体 2(稍微好一点):

Class A {
Q_PROPERTY
signals:
    void valueChanged(int value);
public:
    int value(...
    void setValue(int value) {
        changeValue(value); // to call virtual changeValue
        emit valueChanged( m_value );
    }
protected:
    virtual void changeValue(int newValue) {
        m_value = newValue;
    }
...
}

// We dont touch public methods, but protected:
Class B : public A {
protected:
    /*virtual*/ void changeValue(int newValue) {
        A::changeValue(newValue *2);
    }
}

来自 Qt 文档:

The READ, WRITE, and RESET functions can be inherited. They can also be virtual. When they are inherited in classes where multiple inheritance is used, they must come from the first inherited class.

只需将访问器设为虚拟,它们就会从 vtable 中调用,因此您将获得适合每个不同子类型的正确函数。