Gtk3 заменить виджет ребенок от другой виджет

Я ищу способ удалить виджет из его родителя (что бы это ни было-VBox, сетка,...) и добавьте заменяющий виджет на его место.

нашел ответ, но я не могу заставить его работать с Gtk3.

вот что я пробовал:

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)

но вызов Gtk.ContainerClass.list_child_properties поднимает

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

Он также не будет принимать экземпляр виджета контейнера. Хоть убей, я не могу понять, что я за параметр. должен был пройти.

P. S.: Я знаю, я мог бы добавить еще один виджет между контейнером и виджет ребенка, но я бы предпочел этого не делать.

обновление: Я думаю, это было недостаточно ясно: заменяющий виджет должен быть в том же месте, что и исходный виджет, с теми же свойствами упаковки.

4 ответов


это стало возможным только недавно, начиная с PyGObject 3.14: https://git.gnome.org/browse/pygobject/commit/?h=pygobject-3-14&id=bf84915f89fd5fd502b4fb162eef7bc0a48c8783

одним из следующих будет работать в PyGObject 3.14 и далее:

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

(второй синтаксис-в случае, если методы класса и экземпляра имеют конфликт именования. См. обсуждение здесь.)


благодаря информации, предоставленной ptomato это, вот рабочий код:

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)

Я знаю, как это работает с C , я не пробовал его с 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: в случае VBox или сетки виджет не вставляется в место старого, вы должны указать положение вставки (положение старого whild)

удачи ,


вы можете попробовать reparent() метод Gtk.Штучка. Вы можете проверить документы на данный ссылке. Если я хорошо помню, вы должны сначала reparent дочерний виджет, а затем удалить старый родительский виджет. Если он не работает в комментарии, и я проверю свои документы (в настоящее время не на этой машине sry).