Design von QAbstractTableModel

Alles rund um die Programmierung mit Qt
Antworten
nobody44
Beiträge: 1
Registriert: 5. August 2010 13:56

Design von QAbstractTableModel

Beitrag von nobody44 »

Hallo zusammen,
Ich arbeite mich gerade in Qt ein (C/C++) und habe mein erstes Programm 'fertiggestellt', aber jetzt wo es fertig ist, denke ich, dass ich das ganze falsch angegangen bin.
Zuerst erkläre ich kurz, was das Programm macht:
Ich habe eine SQLite-Datenbank, für die ich eine extra Klasse geschrieben habe um alle Einträge einer Tabelle abzufragen. Diese Klasse speichert die abgefragten Einträge in einem std::vector zwischen.
Diese Daten möchte ich vorerst in nur einer Tabelle darstellen, dazu habe ich eine Klasse geschrieben, die von QTableView erbt und eine, die von QAbstractTableModel erbt. Das TableModel bekommt die Adresse des std::vectors übergeben, sodass es lesenden (und leider auch schreibenden, aber das ließe sich ändern und ist in dem Fall kein Problem) Zugriff auf alle Elemente des vectors hat. Das TableView zeigt mit dem Model die Daten nun an. Klasse Sache... nur gibts ein kleineres Problem:
Es sollen noch manuell Einträge hinzugefügt werden können. Dazu gibt es einen Button und ein Dialog. Nach der Bestätigung des Dialogs wird der Eintrag in die SQLite-Datenbank geschrieben, er wird im vector gespeichert aber nicht in der Tabelle dargestellt. Besser gesagt: Es wird nicht sofort / nicht richtig angezeigt. Denn anfangs ist nur eine neue leere Zeile sichtbar.
Wie teile ich dem TableView möglichst einfach und elegant mit, dass eine neue Zeile hinzugefügt wurde und wieso geschieht das nicht automatisch?
Ich habe es mit beginInsertRows / endInsertRows gelöst, aber das ist doch eigentlich keine Lösung?! Ich finde sie zumindest echt nicht schön :-/...
Also: War es von Anfang an falsch, dem Model einfach die Adresse des vectors zu geben? Wäre es eventuell besser, eine Kopie des vectors zu erstellen, die das Model dann selbst verwaltet?


Ich würde auch gerne ohne QSqlxxxxx auskommen, da ich überlege das Programm erneut unter gtkmm zu schreiben, um beide Bibliotheken besser einschätzen zu können (bin neu in der Linux-Programmierung).

Bin mir jetzt nicht sicher, ob meine Frage verständlich ist und bitte schonmal um Entschuldigung, wenn es zu undeutlich beschrieben ist :-)...
Danke für eure Zeit ;-)
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

Zuerst zwei allgemeine Fragen:

* wozu hast du QTableView abgeleitet?
* warum kein QSqlTableModel?


Dann zu den Fragen:
Wie teile ich dem TableView möglichst einfach und elegant mit, dass eine neue Zeile hinzugefügt wurde und wieso geschieht das nicht automatisch?
Wie soll eine View mitkriegen, dass sich an den Modeldaten was geändert hat? Mit Signals. Du kannst diese Signals entweder selbst emitten, oder aber du lässt das die Baseclass erledigen.. mit "begin/endInsertRows".
Ich habe es mit beginInsertRows / endInsertRows gelöst, aber das ist doch eigentlich keine Lösung?! Ich finde sie zumindest echt nicht schön :-/...
Doch.. das ist die saubere Lösung.
Also: War es von Anfang an falsch, dem Model einfach die Adresse des vectors zu geben? Wäre es eventuell besser, eine Kopie des vectors zu erstellen, die das Model dann selbst verwaltet?
Aus OOP-Sicht war das ganz sicher falsch, besonders wenn dieser Vektor ein Member einer weiteren "Datenbankklasse" ist.

Es gibt viele Varianten, wie du das lösen kannst. Nur einige als Beispiele:

a) Variante "Datenbankmodel"
Du streichst die Datenbankklasse und lässt das alles dein Model machen. Evt. hast du am Ende dann QSqlTableModel nachprogrammiert.

b) Variante "Unabhängiges Model"
Das Model weiss nichts von einer Datenbankklasse und bekommt einfach beim Start alle Daten (als Kopie). Nach dem Bearbeiten kann dann der Kontroller (GUI) die Daten des Models abfragen und in die Datenbank übernehmen.

c) Variante "gekoppelt"
Das Model und die Datenbankklasse sind über Signals/Slots gekoppelt. In diesem Fall würde die GUI nach dem Aufrufen deines "Add-Dialoges" der Datenbankklasse die neuen Daten übergeben und diese wiederum teilt dem Model (nach dem erfolgreichen Speichern) via Signal den neuen Datensatz mit.

hth..


[EDT]
Ich würde auch gerne ohne QSqlxxxxx auskommen, da ich überlege das Programm erneut unter gtkmm zu schreiben, um beide Bibliotheken besser einschätzen zu können
Natürlich kannst du auch direkt libsqlite verwenden und diesen Code dann in gtkmm und in Qt verwenden, aber gerade wenn du die beiden Bibliotheken vergleichen willst, solltest du unbedingt QSql verwenden (um die Mehrarbeit einschätzen zu können, wenn ein Framework kein Datenbankmodul bietet).
Antworten