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).