如何覆盖 Q_Property?

Posted

技术标签:

【中文标题】如何覆盖 Q_Property?【英文标题】:How to override a Q_Property? 【发布时间】:2015-04-16 18:40:53 【问题描述】:

考虑这些类:

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; 

    ...
;

访问属性值时,直接调用Class A的方法,而不是Class B的方法。

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

这是最好的解决方案吗?

有没有人发现潜在的问题(由于属性名称相同)?

【问题讨论】:

【参考方案1】:

来自 Qt 文档:

可以继承 READ、WRITE 和 RESET 函数。他们还可以 是虚拟的。当它们在多个类中被继承时 使用继承,它们必须来自第一个继承的类。

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

【讨论】:

也许我遗漏了什么,但这就是我在提供的示例中所做的。 嗯.. 我想我是... :) 我重新测试过,这次一切正常。显然,在 QML 上,在设置值时不会调用 onValueChanged 方法:B value: 2 onValueChanged: console.log("value " + value) 您可能需要清理项目并重建。当您进行更改时,Qt 经常会出现问题,让所有内容保持最新。【参考方案2】:
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);
    

【讨论】:

我喜欢你巧妙的解决方案,但只要简单的“事情”有效,我就会坚持下去! BTW 始终在设置和发出信号之前检查新值是否不等于现有值。这样可以避免连接和绑定循环。 解决方案 2 在 B 实例上设置值时不起作用,因为在这种情况下不会触发通知信号。发射需要转移到 changeValue 实现,当然应该只在值实际发生变化时触发。

以上是关于如何覆盖 Q_Property?的主要内容,如果未能解决你的问题,请参考以下文章

Q_PROPERTY 发出的信号如何被捕获?

如何通过 Q_PROPERTY 向 QML 公开指向 Q_GADGET 的指针

Qt:如何在 C++ 端而不是 QML 上监视 Q_PROPERTY 更改

创建一个类似 Q_PROPERTY 的宏并提取 __VA_ARGS__

Q_PROPERTY 未显示

Qt之Q_PROPERTY宏理解