pygtk从父节点按名称获取小部件

时间:2012-03-15 15:33:32

标签: python gtk pygtk

我有一个gtk小部件,我想知道在其后代中是否有另一个小部件。如果有,我想返回它,否则返回None。这是一个简单的递归问题,但我似乎无法找到正确的方法。

在glade xml文件中,我有:

  <object class="GtkDialog" id="monkey">
  [...]
       <object class="GtkTreeView" id="ook">

并且对find(my_monkey_object, 'ook')的调用应该返回GtkTreeView对象。 find()应该类似于

def find (node, id):
    if node.XXX() == id: return node
    for child in node.get_children():
        ret = find(child, id)
        if ret: return ret
    return None

我不确定我需要使用哪种XXX()方法。 get_name()看起来很有希望,但返回对象的类名而不是“id”。我使用的版本是pygtk-2.24。

针对同一问题,请参阅此Python GTK+ widget name问题。

请注意,此bug类解释了此问题:我希望构建器ID来自GTK小部件树。可悲的是,这似乎不可能......

3 个答案:

答案 0 :(得分:5)

根据gtk C-api文档,您可以获得这样的glade“id”名称:

name = gtk_buildable_get_name (GTK_BUILDABLE (widget))

对于pygtk,这与

相同
name = gtk.Buildable.get_name(widget)

答案 1 :(得分:1)

我猜你的节点对象是一个gtk.Container派生类。也许isinstance(node, gtk.TreeView)正是您所寻找的。在gtk.Widget - 子类中,本身没有“id”。 id字段属于glade-xml解析器。

我可以提出类似的建议:

def find_child_classes(container, cls):
    return [widget for widget in container.get_children() if isinstance(widget, cls)]

或者保留builder-object并通过以下方式访问实例:builder.get_object('your-object-id')

答案 2 :(得分:0)

This answer有它。

适合使用pygi,它看起来像:

# Copypasta from https://stackoverflow.com/a/20461465/2015768
# http://cdn.php-gtk.eu/cdn/farfuture/riUt0TzlozMVQuwGBNNJsaPujRQ4uIYXc8SWdgbgiYY/mtime:1368022411/sites/php-gtk.eu/files/gtk-php-get-child-widget-by-name.php__0.txt
# note get_name() vs gtk.Buildable.get_name(): https://stackoverflow.com/questions/3489520/python-gtk-widget-name
def get_descendant(widget, child_name, level, doPrint=False):
  if widget is not None:
    if doPrint: print("-"*level + ": " + (Gtk.Buildable.get_name(widget) or "(None)") + " :: " + (widget.get_name() or "(None)"))
  else:
    if doPrint:  print("-"*level + ": " + "None")
    return None
  #/*** If it is what we are looking for ***/
  if(Gtk.Buildable.get_name(widget) == child_name): # not widget.get_name() !
    return widget;
  #/*** If this widget has one child only search its child ***/
  if (hasattr(widget, 'get_child') and callable(getattr(widget, 'get_child')) and child_name != ""):
    child = widget.get_child()
    if child is not None:
      return get_descendant(child, child_name,level+1,doPrint)
  # /*** Ity might have many children, so search them ***/
  elif (hasattr(widget, 'get_children') and callable(getattr(widget, 'get_children')) and child_name !=""):
    children = widget.get_children()
    # /*** For each child ***/
    found = None
    for child in children:
      if child is not None:
        found = get_descendant(child, child_name,level+1,doPrint) # //search the child
        if found: return found