Stack-Ebene zu tief Fehler Rubin Gnome2
-
03-07-2019 - |
Frage
Ich habe eine Gtk :: TreeView mit einem Gtk :: TreeModel und Gtk :: TreeModelFilter. Der Baum Modell ist wie folgt:
category1
--> actual row of data
category2
--> actual row of data
Ich möchte auf die Inhalte der @search_entry filtern, aber ich möchte category1 angezeigt werden, wenn eine Zeile darunter ist noch sichtbar, und category2 versteckt werden, wenn es keine Zeilen darunter noch sichtbar sind. Mein Verständnis von Gtk :: TreeModelFilter # set_visible_func ist, dass Sie das Modell und iter von dem „Kind-Modell“ bekommen, so dass Sie, ob überprüfen das Kind iter anzuzeigen. Diese Funktion wird bei jedem iter im Modell namens Gtk jedes Mal, wenn ich anrufen :: TreeModelFilter # refilter.Therefore Ich sage: Wenn die iter Sie mir nur gaben auf der ersten Ebene ist, den Weg bekommen, Schritt nach unten ein, konvertieren der gleiche Weg auf dem Modell der Filter und verwenden, ob der neue Weg zum Test Sichtbarkeit vorhanden ist.
@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 Zeile
has_visible_children = @tree_filter.convert_child_path_to_path(iter_path) ? true : false
verursacht einen „Diesen Fehler: Stack-Ebene zu tief“ Ausgang für jeden iter.
Es gibt eine unendliche Rekursion hier los ist, aber ich sehe nicht, wo es passiert oder wie kann ich es vermeiden. Ich bin sicher, dass ich über diese falsch denke, aber ich habe ohne einen Durchbruch auf diesen ein paar Tagen am Computer gehackt.
Lösung
refilter
ruft den Block auf jedem Knoten. Der Rückgabewert wird nicht mit dem Knoten gespeichert, obwohl, so egal, wie Sie es tun, wenn Sie den Baum nach unten zu schauen haben, werden Sie sich wiederholende Berechnungen sein.
# 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
Andere Tipps
Ich weiß nichts über Rubin, aber dieser Fehler weist eindeutig in Richtung zu vielen Rekursion Iterationen. muss der Kontext auf dem Stapel für jeden Anruf gespeichert werden, so dass - hurra - a
Stack-Überlauf
:-) Fügen Sie eine Variable Ihre Ebene der Iterationen zu verfolgen und drucken es mit dem Fehler aus. Es ist entweder etwas falsch mit Ihren Daten oder die Rekursion Logik, oder beides.