Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Write function not working for Q_PROPERTY



  • Hello everyone. I'm trying to modify a property of a Q_GADGET using meta-objects. So far I can read the property's name and type, however when I try to read its value or set a value it does not work. Here's my code:

    Q_GADGET:

    #ifndef EXAMPLE_H
    #define EXAMPLE_H
    #include <QObject>
    
    struct Player {
        Q_GADGET
    
    public:
        enum class CarType {
            NO_CAR = 0,
            SLOW_CAR,
            FAST_CAR,
            HYPER_CAR
        }; Q_ENUM(CarType)
    
        Q_PROPERTY(Player player READ getPlayer)
        Q_PROPERTY(int m_speed READ getSpeed WRITE setSpeed)
        Q_PROPERTY(CarType m_carType READ getCarType)
    
        Player getPlayer() { return *this;}
        int getSpeed() {return this->m_speed;}
        void setSpeed(int speed) {this->m_speed = speed;}
        CarType getCarType() { return m_carType;}
    
    
    public:
        CarType m_carType;
        int m_speed;
    
    }; Q_DECLARE_METATYPE(Player)
    
    #endif
    

    Here is my main:

    #include <QCoreApplication>
    #include <iostream>
    #include <QMetaObject>
    #include "example.h"
    #include <QDebug>
    #include <QMetaProperty>
    
    
    template <class T>
    void gadgetExplorer(T *ptr)
    {
        const QMetaObject *mo = &ptr->staticMetaObject;
        qInfo() << "Q_GADGET: " << mo->className();
        QMetaProperty mp = mo->property(1);
        qInfo() << "Q_PROPERTY: " << mp.name();
        //Read player's speed
        QVariant i = mp.readOnGadget(&mp);
        qInfo() << "Q_PROPERTY_VALUE: " << i;
        i = 40;
        //Set a new value = 40
        bool operationSuccess = mp.writeOnGadget((void*)&mp, i);
        qInfo() << "WAS_WRITE_SUCCESSFUL? " << operationSuccess;
    
    }
    
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
        qRegisterMetaType<Player>();
        //Create a player and set the speed
        Player p1;
        p1.setSpeed(30);
        qInfo() << "Player speed before gadgetExplorer: " << p1.getSpeed();
        gadgetExplorer(&p1);
        qInfo() << "Player speed after gadgetExplorer: " << p1.getSpeed();
    
        return a.exec();
    }
    

    Here's what I get from the console:

    Player speed before gadgetExplorer:  30
    Q_GADGET:  Player
    Q_PROPERTY:  m_speed
    Q_PROPERTY_VALUE:  QVariant(int, 21940)
    WAS_WRITE_SUCESSFUL?  true
    Player speed after gadgetExplorer:  30
    

    I was expecting to get a Q_PROPERTY_VALUE of 30, and, after the function is executed, to get a Player speed = 40. However, the results are wrong. What am I doing wrong?

    Thanks for your time.



  • The argument to readOnGadget/writeOnGadget should be the gadget, not the QMetaProperty.

    QVariant i = mp.readOnGadget(ptr);
    bool operationSuccess = mp.writeOnGadget(ptr, i);



  • @raphasauer said in Write function not working for Q_PROPERTY:

    I was expecting to get a Q_PROPERTY_VALUE of 30, and, after the function is executed, to get a Player speed = 40. However, the results are wrong. What am I doing wrong?

    Your QMetaProperty usage is wrong!

    • QVariant i = mp.readOnGadget(&mp); should be QVariant i = mp.readOnGadget(ptr);
    • bool operationSuccess = mp.writeOnGadget((void*)&mp, i); should be bool operationSuccess = mp.writeOnGadget((void*)ptr, i);


  • Thanks @VRonin and @KroMignon for your insights!