Я представил переменную указателя для 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;
};
МойКласс.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;
};
MyClass.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 Framework? Есть предложения?
Также я безуспешно пытался перегрузить оператор равенства в С++.
Обновлять:
Хорошо, я добавляю некоторые уточнения к моему примеру кода, чтобы легче воспроизвести проблему.
Исправлена опечатка в моем примере кода (спасибо @ihor-drachuk). Проблема пока есть.
on*Changed
для объектов работают на назначение/переназначение, но не на изменение внутреннего состояния. Вы должны привязать обработчик к указанному свойству, чтобы получать уведомления при его изменении, а не ко всему объекту. - person folibis   schedule 26.07.2020on*Changed
работает только тогда, когда связанный сигнал испускается, а не когда вы присваиваете значение (как описано в Qt Doc).Fruit
также является свойством, поэтому его сигнал об изменении должен уведомлять qml об изменении. Это работает, как и ожидалось. Но проблема в том, что сигнал изменения не распространяется на второе свойство qml (которое связано с первым свойством). [C++: выдать изменение]=====›[QML: хорошо, изменено]=====›[второе свойство QML: ничего не происходит! :| ] - person S.M.Mousavi   schedule 26.07.2020