[gtkmm] Widget-Komposition ohne Vererbung?



  • Hallo Leudle,

    ich würde gerne ein leicht komplexes gtkmm-Widget erstellen, das sich aus mehreren Standard-Widgets zusammensetzt. Über Vererbung ginge das ja ziemlich einfach, indem meine Widgetklasse von, sagen wir, Gtk::Table erbt, die anderen Widgets erstellt und darin anordnet - diese zugegeben sehr einfache Möglichkeit wird ja auch von den gtkmm-Developern "angepriesen".

    Mit diesem Ansatz hab ich nämlich ein kleines Problem: Mein Widget hat nach außen hin dann ja das Interface einer Gtk::Table , also kann jeder, der es verwenden will, nach Herzenslust die Tabelle manipulieren. Dabei sollte es nach außen hin (wie jede gute Library ;-)) eigentlich eine Blackbox mit rein semantischem Interface sein. Private Vererbung fällt auch raus, denn dann hat es ja nicht mehr das Interface eines Gtk::Widget s und kann nicht mehr verwendet werden, und wenn ich zusätzlich public direkt von Gtk::Widget erbe, hab ich ja einen Mehrfachvererbungs-Diamond.

    Kann ich den Ansatz überhaupt weiterverfolgen oder muss ich das Verhalten sämtlicher Container- und Child-Widgets, die ich verwenden will, selbst programmieren und direkt über Gdk zeichnen?


  • Mod

    Du verwechselst hat-ein mit ist-ein.

    Dein Widget hat einen Table für seine Unterwidgets. Dein Widget selber ist aber kein Table.
    Zumindest hast du die Anforderungen so definiert.
    Dein Hauptwidget sollte also als member einen Table besitzen, der nach aussen hin dann als private oder protected gilt, so das niemand an die Tabelle unbefugt herankommt.

    phlox



  • Ich verwechsle das ganz sicher nicht; ich habe den Eindruck, dass die gtkmm-Developer das verwechseln - immerhin steht in der offiziellen Dokumentation: "gtkmm makes it very easy to derive new widgets by inheriting from an existing widget class, either by deriving from a container and adding child widgets, or by deriving from a single-item widget, and changing its behaviour." Genau den ersten Fall habe ich ja dargestellt. Wenn ich die Table als Member habe und meine Klasse direkt von Gtk::Widget erbt, müsste ich ja immer noch die Table zum zeichnen auf "meine" Zeichenfläche anregen, und wie das gehen soll, habe ich nicht herausfinden können.

    Um ehrlich zu sein ist das Ganze noch etwas komplexer ... eigentlich will ich einen Container basteln, der aus mehreren geschachtelten Standard-Containern (Table und Viewport) besteht. Dadurch stellt sich noch ein Problem: Wenn ich jetzt meinem neuen Container von außerhalb ein Childwidget hinzufügen will, und der steckt es in einen der Member-Container, hat das Childwidget ja dieses Member als Parent, und nicht mein Widget. Nur die Zeichen-Routinen "umzuleiten" (wenn das überhaupt möglich ist), würde also nicht einmal reichen ...


  • Mod

    Also in Qt oder wxWidgets macht man sowas eher über sizer/Layouts, evtl. ist das in GTKmm auch die richtige wahl dann.
    Ansonsten müsstest du klarer beschreiben was du genau machen willst. (Oder ein anderes Framework benutzen ;))



  • Letztendlich will ich eine scrollbare Tabelle, deren Zeilen- und Spaltenüberschriften fixiert sind, also nicht mitscrollen (bzw. nur in einer Dimension statt in zweien). Gewissermaßen wie in Excel/OOo calc, da bleiben die Zeilennummern und die Buchstaben ja auch sichtbar wenn ich mitten im Dokument bin.

    Etwas generischer soll es also eine Tabelle mit mehreren separat scrollbaren horizontalen und vertikalen Unterteilungen werden. Dabei müssen die Zeilenhöhen und Spaltenbreiten natürlich über die Unterteilungen hinweg konstant bleiben.

    Mein Plan war also eine Table, welche unten und rechts mit H- bzw. VScrollbars bestückt ist, und sonst überall mit Viewports, die an die jeweiligen Scrollbars gekoppelt sind. In diesen Viewports muss ich dann natürlich selbst dafür sorgen, dass die eigentlichen Spalten und Zeilen so dargestellt werden wie ich will.

    Ich weiß nicht, ob es einigermaßen verständlich ist, aber ich glaub, ich positioniere einfach alles manuell 😉



  • Hmmm... kein einfacher Fall 🙂 Obwohl Vererbung die "richtigere" Idee wäre, würde ich es vmtl. trotzdem eher über eine Komposition per hat-ein versuchen. Der Nachteil ist, dass du dann kein Gtk::Widget hast (und wenn du doch zusätzlich von Gtk::Widget erbst, dann musst du ein wenig aufpassen... sollte aber machbar sein)... der Vorteil ist, dass du solche Sachen wie "childmember"-adden besser kontrollieren kannst.
    Alternativ doch direkte Vererbung und die Schnittstelle erweitern/verschandeln, so dass du deine Spezialfälle per erweiterter Schnittstelle handelst.

    Edit: :xmas1:


Anmelden zum Antworten