Gtk3 remplacer le widget enfant par un autre widget

je cherche un moyen de supprimer un widget de son parent (quoi que ce soit - une VBox, une grille,...)...) et Ajouter un widget de substitution à sa place.

j'ai trouvé cette réponse, mais je ne peux pas le faire fonctionner avec Gtk3.

Voici ce que j'ai essayé:

from gi.repository import Gtk

def replace_widget(old, new):
    parent= old.get_parent()

    props= {}
    for key in Gtk.ContainerClass.list_child_properties(type(parent)):
        props[key.name]= parent.child_get_property(old, key.name)

    parent.remove(old)
    parent.add_with_properties(new, **props)

Mais l'appel à Gtk.ContainerClass.list_child_properties pose

TypeError: argument self: Expected a Gtk.ContainerClass, but got gi.repository.Gtk.GObjectMeta

il n'accepte pas non plus une instance d'un widget de conteneur. Pour ma vie, je n'arrive pas à trouver quel paramètre je suis censé passer.

P. S.: je sais que je pourrais ajouter un autre widget entre le conteneur et le widget enfant, mais je préférerais ne pas le faire.

mise à jour: je suppose que ce n'était pas assez clair: le widget de substitution est censé être au même endroit que le widget original, avec les mêmes propriétés d'empaquetage.

15
demandé sur Aran-Fey 2014-12-07 16:34:40

4 réponses

cela n'est devenu possible que récemment, depuis la PyGObject 3.14: https://git.gnome.org/browse/pygobject/commit/?h=pygobject-3-14&id=bf84915f89fd5fd502b4fb162eef7bc0a48c8783

L'un ou l'autre des éléments suivants fonctionnera dans PyGObject 3.14 et plus tard:

parent.list_child_properties()
Gtk.ContainerClass.list_child_properties(parent)

(la seconde syntaxe est en classe de cas et les méthodes d'instance ont un conflit de noms. Voir la discussion ici.)

2
répondu ptomato 2014-12-21 06:39:16

Merci aux informations fournies par réponse de ptomato voici le code qui fonctionne:

def replace_widget(old, new):
    parent = old.get_parent()

    props = {}
    for key in Gtk.ContainerClass.list_child_properties(type(parent)):
        props[key.name] = parent.child_get_property(old, key.name)

    parent.remove(old)
    parent.add(new)

    for name, value in props.iteritems():
        parent.child_set_property(new, name, value)
1
répondu Aran-Fey 2018-05-25 05:50:38

je sais comment il fonctionne avec le C , je n'ai pas essayer avec python :

 parent = gtk_widget_get_parent(old);
 g_object_ref(_key); /** because gtk_container_remove remove the widget with its reference we have to increment the number of reference if we want to reuse the old widget **/
 gtk_container_remove(GTK_CONTAINER(parent), old);
 gtk_container_add(GTK_CONTAINER(parent), new);

PS : dans le cas d'une VBox ou de la Grille le widget n'est pas inséré int la place de l'ancien , vous devez spécifier la position d'insertion (la position de l'ancien whild)

bonne chance ,

0
répondu younes zeboudj 2014-12-08 21:42:48

Vous pouvez essayer reparent() méthode de Gtk.Widget. Vous pouvez le vérifier docs à ce lien. Si je me souviens bien vous devriez réparer widget enfant d'abord, puis supprimer Vieux parent widget. Si cela ne fonctionne pas post dans le commentaire et je vais vérifier mes docs (actuellement pas sur cette machine sry).

-1
répondu cyberbrain 2014-12-18 10:17:32