[wxWidgets] wxGrid mit eigener Klasse verbinden
-
Ich hab mich jetzt länger in wxGrid eingearbeitet,
mit dem Ziel, irgendwann es zu ermöglichen, das ich
Klassen, die ihre Daten per Setter und Getter preisgeben,
einfach an das Grid binden zu können, wenn diese in
einer anderen Klasse in einem Container liegen.Damit wollte ich vorallem mir die Arbeit ersparen, für
jede Klasse ein eigenes Grid schreiben zu müssen, wie ich
das noch unter MFC getan habe.Wie gesagt, ich habe häufiger Klassen, wo man die
Daten über Setter und Getter manipulieren kann.
Andere Klassen haben wiederum einen Container der
diese Klasse enthält. Im Grid soll nun der
Inhalt dieses Containers angezeigt werden, und
dort auch gleichzeitig bearbeitbar sein.wxGrid besitzt übrigens nur einen Pointer auf einen
wxGridTableBase, welcher die eigentlichen Daten liefert,
daher findet sich in meinem Beispiel auch ein ganz normales
wxGrid, man muss dieses nicht überschreiben, sondern lediglich
eine Klasse von wxGridTableBase ableiten.Eine Beispielklasse:
class Article { std::string name; std::string id; int number; bool instock; float price; protected: public: Article(std::string name, std::string id, int number); virtual ~Article(); Article(const Article& copy); Article& operator=(const Article& copy); std::string Getname(); void Setname(std::string Name); std::string Getid(); void Setid(std::string Id); int Getnumber(); void Setnumber(int Number); bool Getinstock(); void Setinstock(bool Instock); float Getprice(); void Setprice(float Price); };
Um nun einen Container (std::list<Article>) mit dem Grid zu verbinden,
ist folgender Codeausschnitt nötig:// ein paar werte schon mal in die Liste einfügen... artlist.push_back(Article("Metalplates","23",34)); artlist.push_back(Article("Nails","24",26)); artlist.push_back(Article("Screws","25",12025)); // DataTable erstellen pdatatable = new datagrid::DataTable<Article,std::list<Article>::iterator>(artlist.begin(),artlist.end()); // Die entsprechenden Membervariablen mit den Spalten des Grids verbinden pdatatable->addColumn("Name",new datagrid::TCI_string<Article>(&Article::Setname,&Article::Getname)); pdatatable->addColumn("id",new datagrid::TCI_string<Article>(&Article::Setid,&Article::Getid)); pdatatable->addColumn("Numbers",new datagrid::TCI_int<Article>(&Article::Setnumber,&Article::Getnumber)); pdatatable->addColumn("is in Stock",new datagrid::TCI_bool<Article>(&Article::Setinstock,&Article::Getinstock)); pdatatable->addColumn("Price",new datagrid::TCI_float<Article>(&Article::Setprice,&Article::Getprice,3,2)); // Den DataTable dem wxGrid mitteilen grid->SetTable(pdatatable); // Das Grid initialisieren pdatatable->InitGrid();
Schon zeigt das Grid den Inhalt der Liste an.
Kurze Erklärung der einzelnen Klassen:
DataTable<Type,It> : Die Klasse welche die Daten an das Grid liefert, und auch benachrichtigt wird, wenn Werte geändert wurden.
Type ist die Datenklasse, It der Iterator auf den Container.
TCI_int<Type>: Verbindet eine int-Variable mit einer Spalte im Grid, es müssen
die entsprechenden Handler übergeben werden. TCI steht für TableColumnItem,
welches auch die Basisklasse für alle TCI_* Klassen ist.
TCI_float, TCI_string und TCI_bool verbinden den entsprechenden Datentyp mit einer Spalte im Grid.Das ganze zum Downloaden mit Beispiel gibts hier
phlox
-
Gibt ein Update.
Kurz die Neuerungen:
Klasse DataTable:
Das interface ist jetzt:template<class It, class Type = typename std::iterator_traits<It>::value_type>class DataTable
So kann man bei STL Containern sich den 2. Parameter sparen.
Ebenfalls hat die Klasse nun 2 neue Methoden:
Update(It beg, It end): Das Grid aktualisieren
SetColumnName(int index,wxString name): ColumnHeader umbenennen
Geändert hat sich auch InitGrid, hier wird nun das Grid übergeben:
InitGrid(wxGrid*,bool owntable = true): wxGrid::SetTable wird nun durch die Methode
aufgerufen, und owntable bestimmt dabei ob das Grid den Table mit löscht
wenn es zerstört wird.ebenfalls haben sich die Getter Methoden geändert:
von: type class::Getvarname() zu type class::Getvarname()const
()const macht für Getter einfach mehr Sinn in diesem Kontext.phlox