문제

나는 gtk :: treemodel과 gtk :: treemodelfilter가있는 gtk :: treeview가 있습니다. 트리 모델은 다음과 같습니다.

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

@Search_Entry의 내용을 필터링하고 싶지만, 아래의 행이 여전히 보이면 범주 1을 표시하고, 그 아래에 줄이 여전히 보이지 않으면 Category2가 숨겨져 있기를 원합니다. gtk :: treemodelfilter#set_visible_func에 대한 나의 이해는 "자식 모델"에서 모델과 반복을 가져 와서 자식 반복을 표시할지 여부를 확인할 수 있다는 것입니다. 이 기능은 GTK :: Treemodelfilter#refilter를 호출 할 때마다 모델의 모든 반복에서 호출됩니다. 필터 모델에서 동일한 경로와 새로운 경로가 가시성을 테스트 할 수 있는지 여부를 사용합니다.

@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

라인

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

각 ITER에 대해 "이 오류 : 스택 레벨이 너무 깊은"출력을 유발합니다.

여기에는 무한한 재귀가 일어나고 있지만 어디에서 일어나고 있는지 또는 어떻게 피할 수 있는지 알 수 없습니다. 나는 이것에 대해 잘못된 방법으로 생각하고 있다고 확신하지만, 나는 혁신적인 획기적인 며칠 동안 해킹을 해왔다.

도움이 되었습니까?

해결책

refilter 모든 노드에서 블록을 호출합니다. 그러나 반환 값은 노드와 함께 저장되지 않으므로 어떻게 해야하는지에 관계없이 트리를 내려다 보면 계산을 반복 할 것입니다.

# 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 

다른 팁

나는 루비에 대해 아무것도 모르지만,이 오류는 너무 많은 재귀 반복을 분명히 지적합니다. 컨텍스트는 각 통화마다 스택에 저장되어야합니다.

스택 오버플로

:-) 변수를 추가하여 반복 레벨을 추적하고 오류로 인쇄합니다. 데이터에 문제가 있거나 재귀 로직 또는 둘 다에 문제가 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top