Seite 1 von 1

[erledigt] QVariant Referenz

Verfasst: 29. März 2011 21:59
von Mani99
Hallo,

ich habe ein Problem mit QVariant und Referenzen. Ich übergebe ein QVariant per Referenz an meine Methode, in der Methode möchte ich &item in eine QLinkedList<QVariant> umwandeln, dann QObject der Liste hinzufügen, vorher aber in ein QVariant umwandeln.

Das funktioniert alles soweit, nur steh ich jetzt etwas auf dem Schlauch, wie ich die von QVariant umgewandelte QLinkedList<QVariant> wieder in das &item reinbekomme!

Code: Alles auswählen

void MyClass::getInfo(QVariant &item)
{
    // &item umwandeln in QLinkedList<QVariant> item_list
    // item_list neues Object hinzufügen (QObject umwandeln in QVariant)
    
}
Danke!

Verfasst: 30. März 2011 08:42
von franzf
Wie konvertierst du den Variant in deine List, wenn du nicht weißt, wie die List (oder irgend ein Value) in den Variant bekommst?

Ansonsten wirkt das EXTREMST dreckig! Irgend welche Werte (lies: Werte! Values) in einen QVariant und dann noch in eine QVariant List zu packen, dann auch noch irgendwie erweitern - Pfui! (Sry)
Kannst du mal grob umreißen, um waqs es dir geht, So Ausgangslage, Ziel, ohne auf deine jetzige Implementierung einzugehen? Gibt sicher viele bessere Lösungen.

Das Problem an QVariant ist halt, dass da alles mögliche drinnen stehen kann, und du eigentlich wissen musst, was gerade drin steht. QObject hat mMn. gar nix drinnen verloren (Objektreferenz und kein Value). Ein cast kann ganz schön ins Auge gehen.

Verfasst: 30. März 2011 08:56
von Mani99
Ok, also, ich habe ein xml dokument, welches ich parsen möchte. Die eingelesenen daten möchte ich in einer datenstruktur speichern.

Das mit QObject war nur ein beispiel, es sollen halt alle möglichen datentypen in der struktur gespeichern werden können.

Es gibt die möglichkeit, das ein eintrag (entry) aus einem name und value paar besteht, welches ich in ein QPair einfüge, außerdem gibt es die möglichkeit, das eine liste (entry - list) vorhanden ist, das möchte ich in eine QList/QLinkedList einlesen.

Außerdem besteht noch die möglichkeit, das ein wert der liste wiederum eine liste (welche wiederum listen enthalten kann) ist (verkettete liste), diese soll als liste in die liste eingefügt werden.

Darum war QVariant für mich die einfachste möglichkeit, aber wenn es eine bessere möglichkeit gibt?

Code: Alles auswählen

[...]
<item>
   <entry>
      <name>Eintrag1</name>
      <value>Wert1</value>
   </entry>
   <entry>
      <list>
         <value>Wert1</value>
         <value>Wert2</value>
         <value>Wert3</value>
         <value>
            <list>
               <value>Wert1.1</value>
               <value>Wert1.2</value>
               <value>Wert1.3</value>
            </list>
         </value>
         <value>Wert4</value>
      </list>
   </entry>
</item>
[...]

Verfasst: 30. März 2011 12:26
von franzf
QVariant ist da garantiert keine Lösung. Eine "Datenstruktur" macht nur Sinn, wenn alle Daten darin irgendwie verwandt sind oder etwas miteinander zu run haben.
Schau dir XML an: Du hast lauter Nodes. Eine Node kann jetzt aber verschiedene Ausprägungen haben: Element, Attribute, CDATA, usw. Es gibt daher in den DOM-Implementierungen eine gemeinsame Basisklasse: Node. Die spezialisierten Nodes (Element, ...) erben von Node. Beim Parsen werden die speziellen Klassen instantiiert und als Node in den Dom-Tree eingefügt. Node hat wiederum ein attribut "type", über das die spezielle Klasse identifiziert werden kann. Beim Iterieren über alle nodes eines trees kannst du nun node.tree() anschauen und entsprechend in den korrekten Typ casten.

So viel zur Parallele. Dein Problem lässt sich ähnlich lösen. Erstell dir eine KLasse "BaseObject" (Benennung sollte natürlich passender sein ;)), die alle Eigenschaften implementiert, welche allen Typen gemein ist. Nun kannst du für deine ganzen speziellen Fälle eigene Klassen ableiten. Diese kannst du nun als "BaseObject" in deiner Datenstruktur ablegen. So hast du gleich mehrere Fliegen mit einer Klappe geschlagen:
* Die Daten liegen in der abgeleiteten Klasse so vor wie sie sollen: als konkreter Typ (QPair, ...), nicht als QVariant.
* Du kannst deine Daten direkt identifizieren (Klasse eben), und musst nicht erst halsbrecherisch mit Variants schonglieren (was nebenbei auch ziemlich auf die Performance geht)
* Eine "liste" ist jetzt nicht mehr eine QVariantList, sondern eine parent-node mit children! Das ist SOFORT(!) identifizierbar.
* Typunterscheidung und casten wird zum großen Teil vom Compiler überwacht. Ein falscher Cast zur Lafzeit wie von QVariant auf irgend einen falschen Typ resultiert nicht (so leicht) in einem Laufzeitfehler.

Ich hoffe das war jetzt halbwegs klar. Da du leider noch nicht gesagt hast, was genau modelliert werden soll, kann ich noch keine konkreten (Pseudo)Klassen angeben.

Verfasst: 30. März 2011 12:50
von Mani99
Danke, das hat mich jetzt weiter gebracht!

Ich hatte zwar irgendwann daran gedacht, das mit eigenen klassen zu lösen, die idee aber wieder verworfen, weil ich eben dachte, das das mit QVariant auch funktioniert.

Was genau modelliert werden soll, weiß ich leider auch noch nicht so genau, weil ich momentan "proof of concept" prototypen baue und da kann das ganze modell in den nächsten wochen auch komplett über den haufen geworfen werden.

Aber danke für die hilfe, ich werd mit deinem vorschlag arbeiten!