2014-10-16 21 views
14

Ho il seguente problema.Come esporre le strutture C++ per i calcoli in Qml

Sto sviluppando un modello in C++ e una vista in Qml, collegandoli tramite controller. Nel mio modello eseguo più calcoli. Offro anche agli utenti della mia applicazione la possibilità di scrivere gestori di eventi personalizzati, scritti in qml. Ora mi sono imbattuto in un punto, in cui ho deciso di usare la notazione Punto fisso e ho scritto una corrispondente classe C++. Ora voglio offrire la classe FixedPoint - inclusi tutti i suoi operatori - agli sviluppatori, che decidono di estendere la mia applicazione in Qml. Finora, ho offerto tutti i dati come QProperties, che è richiesto dalle linee guida di codifica. Ma sono aperto ad altre soluzioni per discuterle nella mia squadra. Chiaramente, un punto fisso non è un'identità e gli algoritmi si basano sulla possibilità di copiarlo, cosa che non è consentita quando si eredita da QObject.

Quindi la domanda arriva: come posso esporre una classe/struct C++ a QML, che NON è un'identità?

Un esempio in codice:

struct FixedPoint 
{ 
    FixedPoint(FixedPoint&); 
    FixedPoint& operator=(FixedPoint&); 
    ... 
    int mantissa; 
    int exponent; 
} 

voglio usarlo direttamente in QML come una proprietà (valore) di un QQuickItem scritto in C++:

MyQmlObject{ 
    value{ mantissa: 134; exponent: 3 } 
} 

La proprietà valore è quindi utilizzato in tutti i calcoli in javascript e viene copiato parecchie volte a lungo. Quindi non posso dare valore a una proprietà di tipo FixedPoint *, penso. Ho ragione?

+1

Hai provato a utilizzare 'Q_DECLARE_METATYPE' +' qmlRegisterMetatype'? Nota che in questo caso puoi passare valori solo tramite segnali/slot. Perché, per passare direttamente qualcosa a/da QML, deve essere un 'QObject'. Gli operatori non funzioneranno all'interno di QML, perché non è possibile estendere il linguaggio QML :) –

+1

Puoi avvolgere l'istanza come QVariant se hai solo bisogno di passarlo (ad esempio non devi usarlo nelle espressioni javascript). – sergk

+1

D'altra parte se è necessario utilizzarlo effettivamente in qml, è necessario derivare da QObject o utilizzare QMap . – sergk

risposta

4

Grazie per il vostro aiuto. Abbiamo deciso di utilizzare QObject in ogni caso, ma in modalità Wrapper. Cioè, abbiamo appena creato un FixPointWrapper (che eredita QObject), che contiene un FixedPointValue effettivo. Questo può essere usato per i calcoli allora. Sembra complicato, ma funziona bene. Particolarmente importante per il nostro bene è la possibilità, per copiare e assegnare i valori di FixedPoint. Pertanto, è necessario il wrapper.

//QML 
MyQmlObject{ 
    value {mantissa: 2; exponent: 4} 
} 


//C++ 
class MyQmlObject : public QQuickItem 
{ 
    Q_Property(FixedPointWrapper* value ...) 
} 

class FixedPointWrapper : public QObject 
{ 
    ... 
    public slots: 
     void setValue(FixedPoint){ //Forward to FixedPoint and implement your wanted effect. The same for getter} 
    private: 
    FixedPoint value;  
} 

All'inizio si sentiva come un hack sporco, ma dopo abbiamo trascorso un paio di più pensieri, possiamo vivere con il risultato.

Ancora una volta, grazie per il vostro aiuto.

Problemi correlati