Frage zur Vorgehensweise bei GTK+ - Fensterinhalt verändern
-
Hallo,
ich bin gerade dabei mich in GTK+ einzuarbeiten. Es gibt ja viele schöne Tutorials mit einem Fenster und ein paar widgets, damit hatte ich bisher auch keine Probleme.
Jetzt möchte ich allerdings (in C) ein Programm schreiben, bei dem sich auf Knopfdruck der Inhalt des Fensters ändert. D.h. alles Widgets löschen die aktuell in meinem Fenster sind und mit den neuen füllen.
Ist das überhaupt die richtige Richtung oder macht man das ganz anders?
Muss ich die Widgets alle irgendwie manuell aus dem Baum von unten nach oben free()en oder reicht es einfach das oberste child zu nehmen. Und wenn das so passt, wie macht man das am elegantesten?grüße
-
Eigentlich steht alles in der Dokumentation von GTK+:
<a href= schrieb:
GTK+ Reference Manual">
void gtk_container_remove (GtkContainer *container, GtkWidget *widget);
Removes
widget
fromcontainer
.widget
must be insidecontainer
. Note thatcontainer
will own a reference towidget
, and that this may be the last reference held; so removing awidget
from itscontainer
can destroy thatwidget
. If you want to usewidget
again, you need to add a reference to it while it's not inside acontainer
, usingg_object_ref()
. If you don't want to use widget again it's usually more efficient to simply destroy it directly usinggtk_widget_destroy()
since this will remove it from the container and help break any circular reference count cycles.Der Container ist in deinem Fall das
GtkWindow
, bei Bedarf kannst du auch einGtkAlignment
nehmen, was den Vorteil hat, dass du auf mögliche Änderungen besser vorbereiet bist und weniger Code ändern musst.
Damit du verstehst, wie und wann deineGtkObject
e zerstört werden und um Speicherlecks zu vermeiden, lege ich dir ans Herz das Object memory management zu lesen.Hinzufügen kannst du deine Widgets mit dem Gegenstück zu
gtk_container_remove
, namentlichgtk_container_add
.
-
Danke für den Beitrag, aber das ist noch nicht so ganz was ich suche.
Die Dokumentation und die Funktionen sind mir bekannt, ich hab das ganze auch schon funktionierend umgesetzt.
Und zwar hole ich mir aus dem Fenster mit gtk_container_get_children() die ganzen Widgets und gtk_widget_destroy()e sie dann nach der Reihe. Danach wird die zurückgegebene GList g_list_free()ed.
Ich hoffe mal, damit hinterlasse ich dann keine Speicherlecks mehr.
Was mich an meiner Lösung stört ist, dass ich, wenn ich wieder den gleichen Fensterinhalt anzeigen möchte, die Widgets neu erstellen muss. Lieber wäre es mir, wenn man die Zwischenspeichern könnte, aber ohne dass ich den obersten Container in meine Funktion mit übergeben muss. (ein get_first_child oder sowas wäre da hilfreich)
Immer je nach Fensterinhalt das oberste Element irgendwo in ne globale Variable zu schreiben empfände ich nicht als schöne Lösung.Was mich vor allem Interessiert ist wie man das halt sozusagen als professioneller gtk-Entwickler machen würde, die meisten Tutorials enthalten halt nur Beispiele mit einem Fenster, bei dem sich der Inhalt nicht ändert.
Hier noch meine Code mit dem ich das Fenster leer mache:
void clearMainWindow(GtkWidget *mainWindow) { GList *widgets, *widget; widgets = gtk_container_get_children(GTK_CONTAINER(mainWindow)); widget = g_list_first(widgets); while(widget != NULL) { gtk_widget_destroy(GTK_WIDGET(widget->data)); widget = g_list_next(widgets); } g_list_free(widgets); }