2017-03-14 1 views
2

Je peux émettre des signaux avec des structures étiquetées avec Q_GADGET de C++ vers QML.Comment créer une nouvelle instance d'une structure Q_GADGET dans QML?

Est-il possible d'envoyer une telle structure de QML vers un emplacement C++? Mon code échoue à la première étape: créer une instance dans QML.

Ce code échoue sur la première ligne ...

var bs = new BatteryState() 
bs.percentRemaining = 1.0 
bs.chargeDate = new Date() 
DataProvider.setBatteryState(bs) 

... avec erreur:

qrc:///main.qml:34: ReferenceError: BatteryState is not defined 

je peux émettre un struct BatteryStatus de C++ à QML, mais je voudrais renvoyer un en tant que paramètre unique à un emplacement.

Voici BatteryState.h & BatteryState.cpp:

// BatteryState.h 
#pragma once 

#include <QDate> 
#include <QMetaType> 

struct BatteryState 
{ 
    Q_GADGET 
    Q_PROPERTY(float percentRemaining MEMBER percentRemaining) 
    Q_PROPERTY(QDate date    MEMBER date) 

public: 
    explicit BatteryState(); 
    BatteryState(const BatteryState& other); 
    virtual ~BatteryState(); 
    BatteryState& operator=(const BatteryState& other); 
    bool operator!=(const BatteryState& other) const; 
    bool operator==(const BatteryState& other) const; 

    float percentRemaining; 
    QDate date; 
}; 
Q_DECLARE_METATYPE(BatteryState) 

// BatteryState.cpp 
#include "BatteryState.h" 

BatteryState::BatteryState() 
    : percentRemaining(), date(QDate::currentDate()) 
{} 

BatteryState::BatteryState(const BatteryState& other) 
    : percentRemaining(other.percentRemaining), 
     date(other.date) 
{} 

BatteryState::~BatteryState() {} 

BatteryState&BatteryState::operator=(const BatteryState& other) 
{ 
    percentRemaining = other.percentRemaining; 
    date = other.date; 
    return *this; 
} 

bool BatteryState::operator!=(const BatteryState& other) const { 
    return (percentRemaining != other.percentRemaining 
      || date != other.date); 
} 

bool BatteryState::operator==(const BatteryState& other) const { 
    return !(*this != other); 
} 

I enregistrer ce type dans main.cpp:

qRegisterMetaType<BatteryState>(); 

Recommandations?

+0

http://doc.qt.io/qt-5/qtqml-cppintegration-definetypes.html#registering-an-instantiable-object-type? – bipll

Répondre

2

Vous ne créez pas Q_GADGET s dans QML, les objets QML doivent être QObject dérivés, et sont pas créé par new - qui est pour les objets JS seulement. Les gadgets génèrent juste des méta-données pour que vous puissiez accéder à leurs membres et à ceux de QML et circuler, c'est à peu près tout.

Is it possible send such a struct from QML to a C++ slot?

Il est possible d'envoyer, mais il ne serait pas créé en QML. Il pourrait être retourné à QML à partir d'une fonction C++ ou être exposé en tant que propriété d'un objet.

struct Test { 
    Q_GADGET 
    Q_PROPERTY(int test MEMBER test) 
    public: 
    Test() : test(qrand()) {} 
    int test; 
    Q_SLOT void foo() { qDebug() << "foo"; } 
}; 

class F : public QObject { // factory exposed as context property F 
    Q_OBJECT 
    public slots: 
    Test create() { return Test(); } 
    void use(Test t) { qDebug() << t.test; } 
}; 


    // from QML 
    property var tt: F.create() 

    Component.onCompleted: { 
     F.use(F.create()) // works 
     var t = F.create() 
     console.log(t.test) // works 
     F.use(t) // works 
     console.log(tt.test) // works 
     F.use(tt) // works 
     tt.test = 555 
     F.use(tt) // works 
     t.test = 666 
     F.use(t) // works 
     t.foo() // works 
    }