c++qtqt-signalsqt5.9qproperty

Qt - Q_PROPERTY's NOTIFY signal not emited about MEMBER change


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?


Solution

  • 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.