Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gtk3 replace child widget with another widget

Tags:

python

gtk

gtk3

I'm looking for a way to remove a widget from its parent (whatever that may be - a VBox, a Grid, ...) and add a substitute widget in its place.

I found this answer, but I can't seem to make it work with Gtk3.

Here's what I tried:

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)

But the call to Gtk.ContainerClass.list_child_properties raises

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

It won't accept an instance of a container widget either. For the life of me, I can't figure out what parameter I'm supposed to pass.

P.S.: I know I could add another widget between the container and the child widget, but I'd prefer not to.

UPDATE: I guess it wasn't clear enough: The substitute widget is supposed to be in the same place as the original widget, with the same packing properties.

like image 780
Aran-Fey Avatar asked Dec 07 '14 13:12

Aran-Fey


2 Answers

This has only recently become possible, since PyGObject 3.14: https://git.gnome.org/browse/pygobject/commit/?h=pygobject-3-14&id=bf84915f89fd5fd502b4fb162eef7bc0a48c8783

Either of the following will work in PyGObject 3.14 and later:

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

(The second syntax is in case class and instance methods have a naming conflict. See discussion here.)

like image 116
ptomato Avatar answered Oct 31 '22 10:10

ptomato


Thanks to the information provided by ptomato's answer, here's the working code:

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)
like image 2
Aran-Fey Avatar answered Oct 31 '22 11:10

Aran-Fey