Forum: PC-Programmierung Qt Serialzer QMetaObject/staticMetaObject


von Dirk (Gast)


Lesenswert?

Hallo, ich hätte eine Frage zu dem Code von dem Github Repro

https://github.com/smurfomen/QSerializer/blob/master/src/qserializer.h

In der Header Datei werden #defines getätigt (Zeile 49 - 56) hier der 
Ausschnitt:
1
/* Generate metaObject method */
2
#define QS_META_OBJECT_METHOD \
3
    virtual const QMetaObject * metaObject() const { \
4
        return &this->staticMetaObject; \
5
    } \
6
7
/* Mark class as serializable */
8
#define QS_SERIALIZABLE QS_META_OBJECT_METHOD

Beispiel:

Aus der Datei
 https://github.com/smurfomen/QSerializer/blob/master/example/QSSerialize/main.cpp
1
#include <QCoreApplication>
2
#include "../classes.h"
3
4
#include <QFile>
5
#include <QDebug>
6
7
void json_example() {
8
    qDebug()<<"====================================SERIALIZATION JSON====================================";
9
    Student stud;
10
    stud.age = 23;
11
    stud.name = "Vlad";
12
    stud.links.append("https:/github.com/smurfomen");
13
14
    Parent mother;
15
    mother.age = 43;
16
    mother.male = false;
17
    mother.name = "Olga";
18
19
    Parent father;
20
    father.age = 48;
21
    father.male = true;
22
    father.name = "Alex";
23
    stud.parents.append(mother);
24
    stud.parents.append(father);
25
    qDebug()<<QSerializer::toByteArray(stud.toJson()).constData();
26
}
27
28
Auszug aus der classes.h
29
https://github.com/smurfomen/QSerializer/blob/master/example/classes.h
30
31
class Parent : public QSerializer{
32
    Q_GADGET
33
    QS_SERIALIZABLE
34
    public:
35
    Parent(){ }
36
    Parent(int age, const QString & name, bool isMale)
37
        : age(age),
38
          name(name),
39
          male(isMale) { }
40
    QS_FIELD(int, age)
41
    QS_FIELD(QString, name)
42
    QS_FIELD(bool, male)
43
};
44
45
class Student : public QSerializer {
46
    Q_GADGET
47
    QS_SERIALIZABLE
48
    public:
49
    Student() {}
50
    Student(int age, const QString & name, QStringList links, Parent mom, Parent dad)
51
        : age(age),
52
          name(name),
53
          links(links)
54
    {
55
        parents.append(mom);
56
        parents.append(dad);
57
    }
58
    QS_FIELD(int, age)
59
    QS_FIELD(QString, name)
60
    QS_COLLECTION(QList, QString, links)
61
    QS_COLLECTION_OBJECTS(QList, Parent, parents)
62
};

Fragen:

1. Wann wird das in dem Beispiel aufgerufen?
2. Warum wird staticMetaObject benutzt? Es wird doch hier
1
Student stud;
 eine Instanz des Objekt erstellt und somit sollte QMetaObject reichen 
oder?

von Oliver S. (oliverso)


Lesenswert?

Gegenfrage: Warum willst du das wissen?

Du hast irgendwo in den Tiefen des Netzes einen Code gefunden, den du 
nicht verstehst, und der verwendet mit Qt eine Lib als Basis, die du 
nicht kennst.

Qt bietet u.a. Serialiserung für alle darin bekannten Klassen. Damit das 
auch für selbstdefinierte Klassen funktioniert, braucht es die ganzen 
oben zu sehenden defines und das ganze trallala drumherum.

Die Doku zu Qt steht komplett online, da könntest du nachlesen, wie das 
so alles funktioniert, und warum.

Oliver

von Dirk (Gast)


Lesenswert?

>Gegenfrage: Warum willst du das wissen?
Da ich mich weiter in das QMetasystemeinarbeite.

>Die Doku zu Qt steht komplett online, da könntest du nachlesen, wie das
>so alles funktioniert, und warum.

Nur weil es irgendwo steht heisst es nicht, dass man es Verstanden hat, 
wenn man es gelesen hat, ansonsten bräuchten wir keine Schulen etc. Auch 
ein ganzer Industriezweig e.g. Workshops, Trainings etc. wären 
überflüssig.

Also falls jemand den Grund versteht, wieso staticMetaObject genutzt 
wird und nicht QMetaObject in diesem Beipspiel, dann wäre es hilfreich, 
eventuell sieht jemand mit Mehrerfahrung als ich den Grund.

von Oliver S. (oliverso)


Lesenswert?

Dirk schrieb:
> Also falls jemand den Grund versteht, wieso staticMetaObject genutzt
> wird und nicht QMetaObject
1
const QMetaObject QObject::staticMetaObject
2
3
This variable stores the meta-object for the class.
4
...
5
If you have a pointer to an object, you can use metaObject() to retrieve the meta-object associated with that object.

Deine Frage ist zwar jetzt schon etwas präziser, aber immer noch 
eigentlich sinnlos. staticMetaObject ist ein statischer member von 
QObject, und hat den Typ QMetaObject.

Was also ist jetzt die Frage?

Oliver

von Dirk (Gast)


Lesenswert?

Ja die Beschreibung hab ich gelesen und ich bin mir unsicher, ob man 
Verständnis hier richtig ist.
1
Student stud;

Hier wird ja kein Zeiger auf die Objektinstanz genutzt, deshalb 
staticMetaObject, richtig?
1
Student *stud = new Student()
Hier kann ich wie in der Beschreibung QMetaObject benutzen, weil ich 
einen Zeiger auf das Objekt habe, oder ist mein Verständnis falsch?

von Sven B. (scummos)


Lesenswert?

Lies doch mal die Doku. Da steht (QMetaObject):

A single QMetaObject instance is created for each QObject subclass that 
is used in an application, and this instance stores all the 
meta-information for the QObject subclass. This object is available as 
QObject::metaObject().

von Oliver S. (oliverso)


Lesenswert?

Dirk schrieb:
> oder ist mein Verständnis falsch?

Hm. ich sag mal so: Zum Verständnis fehlen da ein paar sehr grundlegende 
Grundkentnisse über C++. Ich würde an deiner Stelle einen Schritt zurück 
gehen, und erst einmmal davon absehne, so etwas wie Qt "verstehen" zu 
wollen. Ein C++ Grundkurs dagegen wäre hilfreich. Ohne Basics wird das 
nichts.

Nur soviel: Zeiger oder nicht Zeiger haben damit nichts zu tun. 
QMetaObject ist ein Typ.

Oliver

von Sven B. (scummos)


Lesenswert?

Oliver S. schrieb:
> so etwas wie Qt "verstehen" zu wollen

vor allem direkt die kurioseste Detail-Ecke ...

von Dirk (Gast)


Lesenswert?

Ganz hoffnunglos ist es ja nicht.
1
QByteArray testclass::toByteArray() const
2
{
3
    QByteArray ba;
4
    qDebug() << this->staticMetaObject.propertyCount();
5
    qDebug() << this->metaObject()->className();
6
    for(int i = 0; i < this->metaObject()->propertyCount(); i++)
7
    {
8
        auto test = QMetaType::typeName(qMetaTypeId<quint8>());
9
        auto test2 = QString(this->metaObject()->property(i).typeName());
10
        qDebug() << this->metaObject()->property(i).name();
11
        qDebug() << this->metaObject()->property(i).read(this);
12
13
        if(QString(this->metaObject()->property(i).typeName()) == QMetaType::typeName(qMetaTypeId<quint8>()))
14
        {
15
            qDebug() << this->metaObject()->property(i).name();
16
            qDebug() << this->metaObject()->property(i).read(this).constData();
17
            auto t = this->metaObject()->property(i).read(this).constData();
18
            auto s = this->metaObject()->property(i).read(this).Size;
19
            auto u = QMetaType::sizeOf(qMetaTypeId<quint16>());
20
            ba.append(reinterpret_cast<const char*>(t), u);
21
        }
22
23
        if(QString(this->metaObject()->property(i).typeName()) == QMetaType::typeName(qMetaTypeId<quint16>()))
24
        {
25
            qDebug() << this->metaObject()->property(i).name();
26
            qDebug() << this->metaObject()->property(i).read(this).constData();
27
            auto t = this->metaObject()->property(i).read(this).constData();
28
            auto s = this->metaObject()->property(i).read(this).Size;
29
            auto u = QMetaType::sizeOf(qMetaTypeId<quint16>());
30
            ba.append(reinterpret_cast<const char*>(t), u);
31
        }
32
    }
33
    return ba;
34
}

Hier hatte ich ein Teil getestet um mein Verständnis der Dokumentation 
und meines Wissenstandes zuprüfen. Leider hapert es daran wann ich 
staticMetaObject oder wann metaObject benutzen soll. Wie man im Code 
sehen kann benutze ich mal staticMetaObject und mal metaObject und 
beides funktioniert.

von Oliver S. (oliverso)


Lesenswert?

Dirk schrieb:
> Wie man im Code
> sehen kann benutze ich mal staticMetaObject und mal metaObject und
> beides funktioniert.

Ja und?

Oliver

von Sven B. (scummos)


Lesenswert?

Du hast meinen Post oben nicht gelesen, oder?

"A single QMetaObject instance is created for each QObject subclass that
is used in an application, and this instance stores all the
meta-information for the QObject subclass. This object is available as
QObject::metaObject()."

Beides ist dasselbe.

von Dirk (Gast)


Lesenswert?

Anhand deines Postes hab ich gestern nochmal die Dokumentation zum 
QObject gelesen und bin über diesen Abschnitt gestolpert.

Auszug von https://doc.qt.io/qt-5/qobject.html

Example:
1
QObject *obj = new QPushButton;
2
obj->metaObject()->className();             // returns "QPushButton"
3
4
QPushButton::staticMetaObject.className();  // returns "QPushButton"

Danach hab ich mir den Source code vom QObject angeschaut und somit 
wurden beide Eingangsfragen beantwortet bzgl. Makro und 
staticMetaObject/Metaobject

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.