0

我向 qml 公开了一个指针变量,如下所示:

水果:

class Fruit : public QObject
{
    Q_OBJECT
    Q_PROPERTY(int qualityGrade READ qualityGrade WRITE setQualityGrade NOTIFY qualityGradeChanged)
    Q_PROPERTY(bool organic READ organic WRITE setOrganic NOTIFY organicChanged)
public:
    int qualityGrade() const
    {
        return m_qualityGrade;
    }

    bool organic() const
    {
        return m_organic;
    }

public slots:
    void setQualityGrade(int qualityGrade)
    {
        if (m_qualityGrade == qualityGrade)
            return;

        m_qualityGrade = qualityGrade;
        emit qualityGradeChanged(m_qualityGrade);
    }

    void setOrganic(bool organic)
    {
        if (m_organic == organic)
            return;

        m_organic = organic;
        emit organicChanged(m_organic);
    }

signals:
    void qualityGradeChanged(int qualityGrade);

    void organicChanged(bool organic);

private:
    int m_qualityGrade = -1;
    bool m_organic = false;
};

MyClass.h:

class MyClass : public QObject
{
    Q_OBJECT
    Q_PROPERTY(Fruit* featuredFruit READ featuredFruit WRITE setFeaturedFruit NOTIFY featuredFruitChanged)
public:
    explicit MyClass(QObject *parent = nullptr);
    ~MyClass();

    Fruit* featuredFruit() const
    {
        return m_featuredFruit;
    }

public slots:
    void setFeaturedFruit(Fruit* featuredFruit)
    {
        if (m_featuredFruit == featuredFruit)
            return;

        m_featuredFruit = featuredFruit;
        emit featuredFruitChanged(m_featuredFruit);
    }

signals:
    void featuredFruitChanged(Fruit* featuredFruit);

private:

    Fruit* m_featuredFruit = nullptr;
};

我的类.cpp:

MyClass::MyClass(QObject *parent) : QObject(parent)
{
    m_featuredFruit = new Fruit();
    m_featuredFruit->setQualityGrade(2);

    QTimer *timer = new QTimer();
    connect(timer, &QTimer::timeout, this, [=]() {
        //m_featuredFruit->deleteLater();           //<--- activating these two lines causes to force working featuredFruitChanged signal
        //m_featuredFruit = new Fruit();
        m_featuredFruit->setQualityGrade(5);
        emit featuredFruitChanged(m_featuredFruit);
        delete timer;
    });
    timer->start(5000);
}

MyClass::~MyClass()
{
    m_featuredFruit->deleteLater();
    m_featuredFruit = nullptr;
}

我在 QML 中使用它如下:

MyClass {
    id: classObj
    onFeaturedFruitChanged: console.log("original property shows an change");//<--- called as expected
}

Item {
    property Fruit selectedFruit: classObj.featuredFruit //<--- binding qml defined property to C++ property
    
    onSelectedFruitChanged: {
        console.log("binded property recieved change signal");//<--- not called after changes!!!
        alertAnimation.restart();   //<--- an example of usage
    }
}

问题是每当我发出featuredFruitChanged时,绑定 qml 属性都没有收到更改信号。
怎么了?!这是 Qt 框架的错误吗?有什么建议吗?

我也尝试在 C++ 中重载相等运算符但没有成功

更新:

好的,我在示例代码中添加了更多精度,以便更轻松地重现问题。
修正了我的示例代码中的错字(感谢@ihor-dracuk)。问题还存在。

4

1 回答 1

1

因为你拼错featuredFruit了,写了featuedFruit。修复它,它会工作。

更新:如果调用setFeaturedFruit或从 QML 更改它应该可以工作。featuredFruit如果更改某些属性,即使它被选中,它也不会像你期望的那样工作

更新 2:如果更改值,QML 调用 onChanged,值是指向对象的指针。所以如果指针改变了 - 那么 onChanged 将被调用。如果指针后面的东西改变了 - 不。

但是您可以借助以下方法处理它Connections

Connections {
    target: classObj.featuredFruit

    onTargetChanged: console.warn("Target changed!");
    onQualityGradeChanged: console.warn("onQualityGradeChanged!");
    onOrganicChanged: console.warn("onOrganicChanged!");
}

您还可以添加Fruit一些特殊的信号,例如somethingChangedInMe并在每个设置器中发出它。所以,你可以Connections只写这个信号处理程序:

Connections {
    target: classObj.featuredFruit

    onTargetChanged: console.warn("Target changed!");
    onSomethingChangedInMe: console.warn("onSomethingChangedInMe!");
}
于 2020-07-26T09:29:51.853 回答