Frage

Für ein meine Projekte habe ich einen Baum von QObject Objekte abgeleitet, die QObject der Eltern / Kind-Funktionalität nutzen, um den Baum zu bauen.

Dies ist sehr nützlich, da ich Verwendung von Signalen und Slots machen sie, verwenden Qt bewacht Zeiger und erwarten, dass übergeordnete Objekte Kinder zu löschen, wenn sie gelöscht werden.

So weit, so gut. Leider jetzt mein Projekt verlangt von mir, um die Reihenfolge der Kinder zu verwalten / ändern. QObject bietet keine Mittel, um die Reihenfolge ihrer Kinder zu ändern (Ausnahme: QWidget Raise () Funktion - aber das ist in diesem Fall nutzlos). So, jetzt freue ich mich für eine Strategie der die Reihenfolge der Kinder steuern Ich habe ein paar Ideen hatte, aber ich bin mir nicht sicher über ihre Vor-und Nachteile.


Option A: Variable Benutzerdefinierte Sortierindex Mitglied

Verwenden Sie ein int m_orderIndex Membervariable als Sortierschlüssel und bieten eine sortedChildren() Methode, die eine Liste von QObjects kehrt nach diesem Schlüssel sortiert.

  • Einfach zu implementieren in bestehende Objektstruktur.
  • Problematische wenn QObject::children() Methode außer Kraft gesetzt wird - während Schleifen zu Problemen führen, wenn Elemente bestellen geändert wird, auch teurer ist als Standardimplementierung
  • .
  • Sollte auf QObject Objekt Ordnung zurückgreifen, wenn alle Sortierschlüssel sind gleich oder 0 / default.

Option B: Redundante Liste der Kinder

Pflegen Sie eine redundante Liste von Kindern in einem QList, und fügen Sie Kinder es, wenn sie erstellt und zerstört werden.

  • Benötigt teure Verfolgung hinzugefügt / gelöschten Objekte. Diese im Grunde führt zu einem zweiten Kind / Eltern-Tracking und vielen Signale / Slots. QObject tut dies alles intern bereits, so dass es nicht eine gute Idee sein könnte, es wieder zu tun. Auch fühlt sich an wie viel aufblasen für eine einfache Sache hinzugefügt wie die Reihenfolge der Kinder zu verändern.
  • Gute Flexibilität, da ein QList von Kindern verändert werden kann je nach Bedarf.
  • Ermöglicht ein Kind in dem QList mehr als einmal zu sein, oder überhaupt nicht (obwohl es immer noch ein Kind des QObject sein könnte)

Option C: ...

Irgendwelche Ideen oder Anregungen, vor allem von Leuten, die bereits diese, in ihren eigenen Projekten gelöst wird sehr geschätzt. Frohes neues Jahr!

War es hilfreich?

Lösung

Ich verbrachte viel Zeit alle diese Optionen in den letzten Tagen durchlaufen und diskutiert sie sorgfältig mit einigen anderen Programmierern. Wir entschieden uns für Option A zu gehen .

Jedes der Objekte, die wir verwalten ist ein Kind eines Elternobjekt. Da Qt stellt keine Mittel zur Nachbestellung dieser Objekte haben wir beschlossen, für jedes Objekt einer int m_orderIndex Eigenschaft hinzufügen, die standardmäßig auf 0.

Jedes Objekt hat eine Accessorfunktion sortedChildren(), die eine QObjectList der Kinder zurück. Was wir in dieser Funktion zu tun ist:

  1. Verwenden Sie die normale QObject::chilren() Funktion eine Liste aller verfügbaren untergeordneten Objekte erhalten.
  2. dynamic_cast alle Objekte auf unserer "Basisklasse", die die m_orderIndex Eigenschaft bereitstellt.
  3. Wenn das Objekt gießbar ist, fügen Sie ihn in eine temporäre Objektliste.
  4. Verwendung qSort mit einer benutzerdefinierten LessThan Funktion, um herauszufinden, ob qSort die Reihenfolge zweier Objekte ändern muss.
  5. Zurück die temporäre Objektliste.

Wir haben dies aus den folgenden Gründen:

  • Code Bestehende (insbesondere Qt eigener Code) weiterhin children() mit, ohne sich um Nebenwirkungen zu kümmern.
  • Wir können die normale children() Funktion an Orten, wo die Reihenfolge spielt keine Rolle, ohne Leistungsverlust mit.
  • In den Orten, wo wir die geordnete Liste von Kindern müssen wir einfach children() durch sortedChildren() ersetzen und die gewünschte Wirkung erzielen.

Eines der guten Dinge über diesen Ansatz ist, dass die Reihenfolge der Kinder ändert sich nicht, wenn alle Sortier Indizes werden auf Null gesetzt.

Sorry für meine eigene Frage zu beantworten, die Hoffnung, dass die Menschen mit dem gleichen Problem aufklärt. ;)

Andere Tipps

Was ist so etwas wie ...

  1. QList Listchildren = (QList) Kinder ();
  2. sortieren Listchildren
  3. foreach Listchildren setParent (TempParent)
  4. foreach Listchildren setParent (OriginalParent)

Ein gemeiner Hack: QObject :: Kinder () gibt einen Verweis -zu-konst. Sie könnten direkt die const-ness und so manipulieren, um die interne Liste wegzuwerfen.

Das ist ziemlich übel aber, und hat das Risiko Iteratoren ungültig zu machen, die QObject intern hält.

Ich habe nicht eine separate Option C, aber vergleiche Option A und B, Sie sprechen ~ 4 Byte (32-Bit-Zeiger, 32-Bit-Integer) in jedem Fall, so dass ich mit Option B gehen würde, wie Sie können diese Liste halten sortiert.

Um die zusätzliche Komplexität der Verfolgung Kinder zu vermeiden, könnten Sie betrügen und halten Sie Ihre Liste sortiert und ordentlich, aber kombinieren es mit einem sortedChildren Verfahren, dass die Filter aus allen den Nicht-Kinder. Komplexität klug, diese aught um am Ende O (nlogm) (n = Kinder, m = Listeneinträge, unter der Annahme, dass m> = n, das heißt Kinder werden immer hinzugefügt), wenn Sie eine große Wende auf Kinder haben. Nennen wir diese Option C.

Quicksort, in der vorgeschlagenen Option A, gibt Ihnen O (n2) (wc), aber erfordert, dass Sie auch retreive Zeiger, verfolgen sie, retreive eine ganze Zahl, usw. Die kombinierte Methode braucht nur eine Liste der Zeiger (aught sein O (n)).

Ich hatte das gleiche Problem, und ich löste es, indem Option B. Tracking ist nicht so schwierig, erstellen Sie einfach eine Methode „Leere addChild (Typ * ptr);“ und ein anderer eine childitem zu löschen.

Sie müssen nicht von bösen Redundanz leiden, wenn Sie ausschließlich an die Kinder speichern innerhalb des privaten / öffentlichen childlist (QList) jedes Element und legen Sie die QObject Basis. Es ist eigentlich ganz einfach, Auto-Kind-frei auf frei umzusetzen (obwohl das einen zusätzlichen übergeordneten Zeiger erfordert).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top