I have a private class member variable status
and i want to emit a signal with its value everytime it changes. Therefore I use Q_PROPERTY
and specify a signal with NOTIFY
:
#ifndef CAMERACONTROL_H
#define CAMERACONTROL_H
#include <QObject>
#include <iostream>
class CameraControl : public QObject
{
Q_OBJECT
Q_PROPERTY(QString status MEMBER status NOTIFY statusChanged)
private:
QString status;
public:
explicit CameraControl(QObject *parent = nullptr);
~CameraControl();
void changeStatus()
{
std::cout << "changeStatus called" << std::endl; // The function definitely gets called!
this->status = "Change status again!";
}
public slots:
void outputStatus(const QString &status) {
std::cout << status.toStdString() << std::endl;
}
signals:
void statusChanged(const QString &status);
};
#endif // CAMERACONTROL_H
I connect
the statusChanged
signal with the outputStatus
slot inside the constructor:
#include "CameraControl.h"
CameraControl::CameraControl(QObject *parent) :
QObject(parent)
{
this->cameraHandle = nullptr;
this->connect(this, &CameraControl::statusChanged, this, &CameraControl::outputStatus);
this->status = "Change status text";
}
When running the application and change the status through another object i get no ouput and also no message from qt regarding this issue.
Please be aware that this is not the actual implementation. The status
get changed through various member functions quite a lot without any output. However the connect
call aswell as the statusChanged
and the outputStatus
are exactly implemented as in this question.
Because the Q_PROPERTY
has the same name then the member i thought about this being an issue and changed the Q_PROPERTY
to the following without any difference:
Q_PROPERTY(QString qstatus MEMBER status NOTIFY statusChanged)
Does anyone has a clue where the problem lies?
NOTIFY
tells Qt that you will emit the statusChanged
signal when you change the property. It will also cause Qt to emit the signal if the property is modified but it will not emit the signal when you change the class member that backs the property. It doesn't cause the signal to be emitted when you change the value of the property.
You need to implement this yourself, e.g.:
void setStatus(QString value)
{
if (value != status)
{
status = value;
emit statusChanged;
}
}
Alternatively if you call setProperty
this will cause the signal to be emitted automatically:
void setStatus(QString value)
{
setProperty("status", value);
}
Note this is likely to be slower than implementing the previous method as it involves wrapping value in a QVariant
and then doing a lookup through the objects meta information.