0
votes

I basically just want to use multiple derived classes to change a member variable of a base class and to forward that value to qml using qproperty, but emitting the signal isn't working and I am not able to make the signal static

car.h

    #include <QObject>

    class Car : public QObject{
        Q_OBJECT
        Q_PROPERTY(int seats MEMBER m_seats NOTIFY updateSeats)

    public:
        explicit Car(QObject *parent = 0);
        ~Car();
        static int m_seats;

    signals:
        void updateSeats();
    };

car.cpp

    #include "car.h"

    Car::Car(QObject *parent) :
        QObject(parent)
    {

    }

    int Car::m_seats = 0;

    Car::~Car(){}

toyota.h

    #include "car.h"

    class Toyota : public Car{
        Q_OBJECT


    public:
        explicit Toyota(QObject *parent = 0);
        ~Toyota();
        Q_INVOKABLE void foundCar();
    };

toyota.cpp

    #include "toyota.h"

    Toyota::Toyota(QObject *parent) 
    {

    }

    Toyota::foundCar(){
        m_seats = 4;
        emit updateSeats();  // This isn't working
    }

    Toyota::~Toyota(){}

main.cpp

    #include <QGuiApplication>
    #include "car.h"
    #include "toyota.h"

    int main(int argc, char *argv[])
    {

        QGuiApplication app(argc, argv);
        Car car = new Car();
        Toyota ty = new Toyota();
        QQmlApplicationEngine engine;
        QQmlContext *ctxt = engine.rootContext();
        ctxt->setContextProperty("car", car);
        ctxt->setContextProperty("toyota", ty);
        engine.load(QUrl(QLatin1String("qrc:/main.qml")));

        app.exec();
        engine.quit();
    }

In qml when I print car.seats after invoking the foundCar function

main.qml

    toyota.foundCar()
    console.log(car.seats)

the output is still 0. The reason the signal being emitted is not updating is probably because it is from a different object (Toyota). So how can I emit the signal of the base class from the derived class?

1

1 Answers

1
votes

Your toyota and car properties are two separate ones.

You have to read the seats property from toyota:

main.qml

toyota.foundCar()
console.log(toyota.seats) //<--- here

Update after comment:

Ok, that's a different approach, but in that case I would set the car property to the toyota pointer:

main.cpp

    Car car = new Toyota();

    ctxt->setContextProperty("car", ty);
    ctxt->setContextProperty("toyota", ty);

This probably can be fitted in a overarching class (something like car_manager or car_store) in which you have a list of available cars and a function to select one car as the current, then you update the generic car or current property of that overarching class.

I say this because you will get nasty code when you want to work from the root context and furthermore, root properties don't signal that they are changed