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.

War es hilfreich?

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top