2009-03-04 12 views
0

Ich habe eine Gtk :: TreeView mit einem Gtk :: TreeModel und einem Gtk :: TreeModelFilter. Der Baum Modell ist wie folgt:Stack-Level zu tief Fehler Ruby-Gnome2

category1 
    --> actual row of data 
category2 
    --> actual row of data 

ich auf den Inhalt @search_entry filtern wollen, aber ich will category1 angezeigt werden, wenn eine Zeile darunter ist noch sichtbar, und category2 versteckt werden, wenn es keine Reihen darunter noch sichtbar. Mein Verständnis von Gtk :: TreeModelFilter # set_visible_func ist, dass Sie das Modell und Iter vom "Kindmodell" erhalten, so dass Sie überprüfen können, ob das Kind iter angezeigt werden soll. Diese Funktion wird jedes Mal, wenn ich Gtk :: TreeModelFilter # refilter anrufe, auf jedem Iter im Modell aufgerufen. Daher sage ich: Wenn das Iter, das Sie mir gegeben haben, auf der ersten Ebene ist, erhalten Sie den Pfad derselbe Pfad im Filtermodell und Verwendung, ob der neue Pfad vorhanden ist, um die Sichtbarkeit zu testen.

@store = Gtk::TreeStore.new(Gdk::Pixbuf, String, String, Menagerie::Program, TrueClass) 
@tree_filter = Gtk::TreeModelFilter.new(@store) 
@treeview.model = @tree_filter 

# @first_time gets set to false after the model is loaded the first time 
@first_time = true 
@tree_filter.set_visible_func do |model, iter| 
    has_visible_children = true 
    begin 
    iter_path = iter.path 
    if iter_path.depth == 1 && @first_time != true 
     iter_path.down! 
     has_visible_children = @tree_filter.convert_child_path_to_path(iter_path) ? true : false 
    end 
    rescue => e 
    puts "THIS ERROR: " + e.message 
    end 
    unless @search_entry.text == "" 
    if [1,2].collect {|i| iter[i] =~ /#{@search_entry.text}/i }.any? 
     true 
    elsif iter[4] == true and has_visible_children 
     true 
    else 
     false 
    end 
    else 
    true 
    end 
end 

Die Linie

has_visible_children = @tree_filter.convert_child_path_to_path(iter_path) ? true : false 

verursacht einen "diesen Fehler: Stapelebene zu tief", Ausgabe für jeden iter.

Hier läuft eine unendliche Rekursion, aber ich sehe nicht, wo es passiert oder wie ich es vermeiden kann. Ich bin mir sicher, dass ich darüber falsch nachdenke, aber ich habe das ein paar Tage lang ohne Durchbruch durchgespielt.

Antwort

1

refilter ruft den Block auf jedem Knoten auf. Der Rückgabewert wird jedoch nicht mit dem Knoten gespeichert. Wenn Sie also in der Baumstruktur nach unten schauen müssen, wiederholen Sie die Berechnungen.

# Simplified version - returns true if search_text found in iter or any of its 
# first-level children. 
# Let's assume you add a method to GTK::TreeIter: 
# def has_text? search_text 
#  self[1] =~ /#{search_text}/i or self[2] =~ /#{search_text}/i 
# end 
@tree_filter.set_visible_func do |model, iter| 
    next true if @search_entry.text.empty? # No filtering if no search text 
    next true if iter.path.depth == 0  # Always show root node 
    next true if iter.has_text? @search_entry.text 

    if child_iter = iter.first_child # Then we have children to check 
    has_visible_children = false 
    loop do 
     has_visible_children ||= child_iter.has_text? @search_entry.text 
     break unless child_iter.next! # returns false if no more children 
    end 
    next has_visible_children 
    end 

    next false # Not root, doesn't contain search_text, has no children 
end 
+0

Okay, ich verstehe. Wir können alles aus dem TreeModel herausfinden, ohne uns Gedanken über den TreeModelFilter machen zu müssen. Und du hast meinen Code aufgeräumt! Danke, Sarah. – method

1

Ich weiß nichts über Ruby, aber dieser Fehler zeigt eindeutig auf zu viele Rekursion Iterationen. muss der Kontext auf dem Stapel für jeden Anruf gespeichert werden, so dass - hurra - ein

stack overflow

:-) eine Variable Fügen Sie Ihre Ebene der Iterationen zu verfolgen und es aus mit dem Fehler drucken. Entweder stimmt etwas nicht mit Ihren Daten oder der Rekursionslogik oder beides.

Verwandte Themen