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 from container . widget must be inside container . Note that container will own a reference to widget , and that this may be the last reference held; so removing a widget from its container can destroy that widget . If you want to use widget again, you need to add a reference to it while it's not inside a container , using g_object_ref() . If you don't want to use widget again it's usually more efficient to simply destroy it directly using gtk_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 ein GtkAlignment 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 deine GtkObject 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 , namentlich gtk_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);
    }
    

Log in to reply