2010-07-06 8 views
14

Ich arbeite an einer Mapping-Anwendung und muss die Datenobjekte mithilfe einer Tabelle, eines Formulars und als grafische Objekte in der Map anzeigen. Ich verwende PyQt, aber das ist nicht wirklich wichtig, da dies eine Qt-Frage und keine Python-Frage ist.So verwenden Sie Qt Model/View-Framework mit dem Graphics View-Framework

Wenn ich nur die Tabellen- und Formularansichten benötigte, wäre das einfach, ich würde einfach das Qt Model/View-Framework verwenden. Allerdings brauche ich die Kartenansicht, um Funktionen zur Verfügung zu stellen, die nur mit Hilfe des Graphics View-Frameworks verfügbar sind. Dies ist im Wesentlichen ein eigenes Model/View-Framework, wobei QGraphicsScene als Datenmodell fungiert.

Ich kann mir zwei Möglichkeiten vorstellen, dies zu tun. Man würde mit einem autoritativen Modell beginnen, das von QAbstractItemModel abgeleitet wurde, es mit einer Unterklasse von QAbstractItemView verknüpfen und von dort QGraphicsItems in der Szene generieren und aktualisieren. Das sieht jedoch hässlich aus, da ich nicht sicher bin, wie ich mit den Benutzerinteraktionen mit und den Änderungen an den Datenelementen durch die Interaktion mit den QGraphicsItems umgehen soll.

Die andere Möglichkeit, die ich tun kann, ist, QGraphicsScene als die autorisierende Datenquelle zu behandeln und das Datenobjekt in jeder Eigenschaft Q.graphicsItem .data() zu speichern. Ich würde dann QAbstractItemModel ableiten und so schreiben, dass es auf die Daten in der Szene als Datenspeicher zugreift, die anderen Ansichten würden dies dann als ihr Modell verwenden. Wie würde ich Änderungen an den Daten in der Szene auf das Modell übertragen?

Egal, welchen Ansatz ich nehme, es sieht so aus, als gäbe es eine Lücke, die von den Frameworks nicht behandelt wird. In Model/View wird angenommen, dass alle Änderungen im Modell vorgenommen werden. In der Grafikansicht wird angenommen, dass alle Änderungen in der Szene vorgenommen werden.

Also welchen Ansatz würden Sie wählen QAbstractItemModel (autorisierend) -> QAbstractItemView-> QGraphicsScene oder alternativ QGraphicsScene (autorisierend) -> QAbstractItemModel-> Andere Ansichten. Warum würdest du eins vor dem anderen wählen und was hast du erwartet? Hat noch jemand diese Lücke zwischen Qt's Twin Model/View Frameworks schließen müssen und wie haben Sie das gemacht?

Antwort

10

QAbstractItemModel (autorisierenden) -> QAbstractItemView-> QGraphicsScene

Ohne Zweifel. Ich habe das schon einmal gemacht, es erfordert ein bisschen Duplikation (zumindest einige, die ich nicht vermeiden konnte), aber nichts zu schlecht.

Dies ermöglicht Ihnen auch, Ihre Daten in Standardansichten zusammen mit der Szene darzustellen, die ganz nett ist.

Mein bester Rat wäre, ein QHash von QPersistantModelIndex-QGraphicsItem zu speichern und ein QGraphicsScene im QAbstractItemView Du erstellen. Dies ermöglicht es Ihnen, schnell zwischen Model/View Land (QModelIndex) zu Graphics View Land zu gehen (QGraphicsItem)

+0

Dies ist der Ansatz, mit dem ich begonnen habe, bevor ich erkannte, dass ich es anders herum tun könnte. Ich schätze, die einzigen Methoden von AQbstractItemView, die ich zur Unterklasse benötige, sind dataChanged(), rowsInserted() und rowsAboutToBeRemoved()? Verwalten Sie dann die Elemente in der Szene entsprechend. Ich erwarte, dass ich QPersistentModelIndexes in den QGraphicsItems speichern werde. Ich mag die QHash-Idee. Ich verwende PyQT, also würde ich ein Python-Wörterbuch verwenden, aber es ist eine nette Optimierung. –

+0

@Simon: Yep Ich denke, Sie haben es, in DataChanged() müssen Sie möglicherweise einige der Code aus der QGraphicsScene abhängig von Ihren Daten und Darstellung, aber wieder, es sollte gering, wenn überhaupt. –

+0

Es funktioniert, auf einer grundlegenden Ebene. Yay! –