2017-06-12 3 views
3

Ich muss einen Zeiger auf eine benutzerdefinierte Klasse in Qml mit QQmlContext::setContextProperty() zuweisen. Ein anderes qml-Objekt hat Q_PROPERTY desselben Typs, um es erneut abzurufen.QVariant mit benutzerdefinierten Klassenzeiger gibt nicht die gleiche Adresse zurück

Ein einfacher Test zeigte mir, dass die Konvertierung nicht funktioniert, wie ich dachte.

#include <QCoreApplication> 
#include <QDebug> 
#include <QMetaType> 

class TestClass 
{ 
public: TestClass() { qDebug() << "TestClass()::TestClass()"; } 
}; 

Q_DECLARE_METATYPE(TestClass*) 

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

    qDebug() << "metaTypeId =" << qMetaTypeId<TestClass*>(); 

    auto testObject = new TestClass; 
    QVariant variant(qMetaTypeId<TestClass*>(), testObject); 
    auto test = variant.value<TestClass*>(); 

    qDebug() << testObject << variant << test; 

    return 0; 
} 

Diese winzige Testanwendung gibt mir eine Ausgabe wie folgt:

metaTypeId = 1024 
TestClass::TestClass() 
0x1b801e0 QVariant(TestClass*,) 0x0 

ich wirklich wieder die gleichen Zeiger heraus erhalten möchte, nachdem es bis zu einem QVariant konvertieren. Später werde ich es einem qml-Kontext zuweisen und dann muss die Konversation korrekt funktionieren.

+0

[ 'QVariant :: value'] (http: //doc.qt .io/qt-5/qvariant.html # value): * Wenn der in der QVariante gespeicherte Zeiger zu t in qobject_cast gesetzt werden kann, wird das Ergebnis zurückgegeben. Andernfalls wird ein Nullzeiger zurückgegeben. Beachten Sie, dass dies nur für QObject-Unterklassen funktioniert, die den Makro Q_OBJECT verwenden. * Wenn Sie einen Zeiger in 'QVariant' speichern wollen, müssen Sie ihn als' void * 'speichern. – thuga

+0

Wenn ich void * als QVariant-Type verwenden würde, kann 'Q_PROPERTY' für die Verbindung mit qml immer noch eine' TestClass * 'sein? Ich kann das Q_OBJECT-Makro nicht zu der Klasse hinzufügen, die ich über qml transportieren möchte, weil die Klasse nicht von mir geschrieben wurde. –

+0

Was ist das Ziel, ein Objekt an QML zu übergeben, das nicht dafür entworfen wurde? – m7913d

Antwort

3

Dies funktioniert für mich Qt 5.9:

#include <QVariant> 
#include <QDebug> 

class CustomClass 
{ 
public: 
    CustomClass() 
    { 
    } 
};  
Q_DECLARE_METATYPE(CustomClass*) 

class OtherClass 
{ 
public: 
    OtherClass() 
    { 
    } 
}; 
Q_DECLARE_METATYPE(OtherClass*) 

int main() 
{ 
    CustomClass *c = new CustomClass; 
    OtherClass *o = new OtherClass; 
    QVariant v; 
    v.setValue(c); 
    QVariant v2; 
    v2.setValue(o); 

    qDebug() << v.userType() << qMetaTypeId<CustomClass*>() << v2.userType() << qMetaTypeId<OtherClass*>(); 
    qDebug() << v.value<CustomClass*>() << c << v2.value<OtherClass*>() << o; 

    return 0; 
} 

Und die Ausgabe ich habe:

1024 1024 1025 1025 
0x81fca50 0x81fca50 0x81fca60 0x81fca60 
+0

Dies funktionierte für mich nach dem Hinzufügen eines qRegisterMetaType –

1

Wie @thuga in den Kommentaren erwähnt, müssen Sie void* und static_cast zusammen mit QVariant::fromValue verwenden.

#include <QCoreApplication> 
#include <QDebug> 
#include <QMetaType> 

class TestClass 
{ 
public: TestClass() { qDebug() << "TestClass()::TestClass()"; } 
}; 

Q_DECLARE_METATYPE(TestClass*) 

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

    qDebug() << "metaTypeId =" << qMetaTypeId<TestClass*>(); 

    auto testObject = new TestClass; 
    QVariant variant(QVariant::fromValue(static_cast<void*>(testObject))); 
    auto test = static_cast<TestClass*>(variant.value<void*>()); 

    qDebug() << testObject << variant << test; 

    return 0; 
} 
+0

Kann ich einen Wrapper verwenden, der von Qobject stammt? –

Verwandte Themen