Konzept: 100% Menu Abstraktion
Verfasst: Di Okt 12, 2010 1:52 am
Hier nur ein kleines Konzept, wie ihr bei Qt oder auch generell anderen Toolkits die kompletten Menus 100% abstrahieren könnt und ihr euch dadurch nicht, mit im meinen Fall, irgendwelchen QString's, Q_OBJECTs o.ä. rumschlagen müsst, welche die Portabilität auf andere Widget toolkits in der Zukunft z.b. massiv behindern bis unmöglich machen. Insbesondere da ich das GUI durch Python erstellen wollte, sodass der User sich schnell alles anpassen kann...
Das Konzept ist einfach, es gibt drei Funktionen, die alles regeln und eine statische Funktion die es ausführt, diese statische wird z.b. von den QActions mit irgendwelchen Daten aufgerufen z.b. Callbacks, Integer - bei mir sind es Strings - wonach diese dann halt die entsprechende Aktion einleitet.
Die Menus werden in einem Container nach Wahl mit Index Zugriff gespeichert, ich meine damit die Menus(z.b. QMenu), nicht die Actions.
Alle drei funktionen nehmen je einen - bei mir - unsigned int an, welcher die MenuID darstellt, ist dieser 0 wird die Aktion auf der Haupt MenuBar ausgeführt, ist dieser größer als 0 wird die Aktion auf dem Menu an Containerposition der um eins verringerten MenuID ausgeführt.
Die Parameter dürften für sich selber sprechen:
unsigned int createMenu(const char *name, unsigned int anchorid);
Diese Funktion erstellt ein Menu, wenn z.b. die anchorid out of range ist wird 0 zurückgeben (0 ist invalid da Hauptmenubar id)
bool createSeparator(unsigned int menuid);
Ist klar
bool createCommand(unsigned int menuid, const char* cmd, const char * text, const char* descr, const char* shortcut);
Erstellt eine Aktion, bei mir halt mit einem String als command welcher bei mit in einer QAction durch setData() (siehe Qt Docs) gespeichert wird.
Bei den letzeren zwei Funktionen gibts noch das Problem, das die Hauptmenubar nicht bei allen Widget Toolkits direkt Aktionen oder Horizontale Seperatoren unterstützt, in diesem Fall wird halt false zurückgegeben.
Je nach Toolkit oder je nachdem wie sauber ihr das implementiert, könnt ihr das in ~20 - 40 Zeilen Code runterrattern, bei mir sinds derzeit um die 120.
Ein Beispiel mit dem Interface Code(sind bei mir Klassenfunktionen, hab das aber mal weggelassen...);
Das obrige Konzept lässt sich auch prima auf Tabs anwenden. Ich hab keine Funktionen um auch wieder Zeugs zu entfernen, in diesem Fall wird der komplette MenuBar inhalt gelöscht und komplett neu aufgebaut, lässt sich jedoch auch implementieren, wenn die Funktionen zum hinzufügen von Commands und Separatoren auch ein index zurückgeben und die Actions auch gespeichert werden...
Auf Gtk+ und Motif dürfte die Abstraktion auch ohne weiteres implementierbar sein, wenn ich mich recht erinnere(schon lange nixmehr damit gemacht) bei gtkmm wirds allerdings witzig da da die Menus per XML gebaut werden und sich kaum noch Aktuelle docs oder Beispiele mehr finden wie das auch ohne geht, mit einer der Gründe warum ich generell von gtkmm fern bleibe und Gtk+ ist für mich zu langsam und in C daher auch keine Alternative zu Qt...
Qt's the best - even if it's reinventing the wheel...
Das Konzept ist einfach, es gibt drei Funktionen, die alles regeln und eine statische Funktion die es ausführt, diese statische wird z.b. von den QActions mit irgendwelchen Daten aufgerufen z.b. Callbacks, Integer - bei mir sind es Strings - wonach diese dann halt die entsprechende Aktion einleitet.
Die Menus werden in einem Container nach Wahl mit Index Zugriff gespeichert, ich meine damit die Menus(z.b. QMenu), nicht die Actions.
Alle drei funktionen nehmen je einen - bei mir - unsigned int an, welcher die MenuID darstellt, ist dieser 0 wird die Aktion auf der Haupt MenuBar ausgeführt, ist dieser größer als 0 wird die Aktion auf dem Menu an Containerposition der um eins verringerten MenuID ausgeführt.
Die Parameter dürften für sich selber sprechen:
unsigned int createMenu(const char *name, unsigned int anchorid);
Diese Funktion erstellt ein Menu, wenn z.b. die anchorid out of range ist wird 0 zurückgeben (0 ist invalid da Hauptmenubar id)
bool createSeparator(unsigned int menuid);
Ist klar
bool createCommand(unsigned int menuid, const char* cmd, const char * text, const char* descr, const char* shortcut);
Erstellt eine Aktion, bei mir halt mit einem String als command welcher bei mit in einer QAction durch setData() (siehe Qt Docs) gespeichert wird.
Bei den letzeren zwei Funktionen gibts noch das Problem, das die Hauptmenubar nicht bei allen Widget Toolkits direkt Aktionen oder Horizontale Seperatoren unterstützt, in diesem Fall wird halt false zurückgegeben.
Je nach Toolkit oder je nachdem wie sauber ihr das implementiert, könnt ihr das in ~20 - 40 Zeilen Code runterrattern, bei mir sinds derzeit um die 120.
Ein Beispiel mit dem Interface Code(sind bei mir Klassenfunktionen, hab das aber mal weggelassen...);
Code: Alles auswählen
unsigned int fileid, editid;
fileid = createMenu("File");
editid = createMenu("Edit");
createCommand(fileid, "new", "New...", "Creates a new file", "CTRL+N");
// [...]
createCommand(editid, "undo", "Undo", "Undo last action", "CTRL+Z");
createCommand(editid, "redo", "Redo", "Redo last action", "CTRL+Y");
unsigned int historystack = createMenu("Undo/Redo Stack", editid);
createCommand(historystack, "undoSz", "Undo Stack Size...", "Set the Undo Stack Size");
createCommand(historystack, "redoSz", "Redo Stack Size...", "Set the Redo Stack Size");
Auf Gtk+ und Motif dürfte die Abstraktion auch ohne weiteres implementierbar sein, wenn ich mich recht erinnere(schon lange nixmehr damit gemacht) bei gtkmm wirds allerdings witzig da da die Menus per XML gebaut werden und sich kaum noch Aktuelle docs oder Beispiele mehr finden wie das auch ohne geht, mit einer der Gründe warum ich generell von gtkmm fern bleibe und Gtk+ ist für mich zu langsam und in C daher auch keine Alternative zu Qt...
Qt's the best - even if it's reinventing the wheel...