2009-03-04 6 views
0

私はGtk :: TreeModelとGtk :: TreeModelFilterを持つGtk :: TreeViewを持っています。スタックレベルが深すぎるエラーRuby-Gnome2

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

、私は@search_entryの内容でフィルタしたいが、私はそれの下の行がまだ表示されている場合はカテゴリ1を表示させたいとカテゴリ2を非表示にするがある場合は、no:ツリーモデルは、このようなものですその下の行はまだ表示されます。私のGtk :: TreeModelFilter#set_visible_funcの理解は、モデルとiterを "子モデル"から取得し、子iterを表示するかどうかをチェックできるようにすることです。この関数は、私がGtk :: TreeModelFilter#refilterを呼び出すたびにモデル内のすべてのiterで呼び出されます。したがって、私は言っています:あなたがちょうど私に与えたiterが最初のレベルにあり、パスを取得し、フィルタのモデル上で同じパスを使用し、可視性をテストするために新しいパスが存在するかどうかを使用します。

@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 

は "THIS ERROR:スタックレベルが深すぎ" の原因となっている各ITERのための出力を。

ここには無限回帰がありますが、どこに起こっているのか、どのように回避できるのか分かりません。私はこれについて間違った考え方をしていると確信していますが、私は突破口なしでこれを数日間ハッキングしています。

答えて

1

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 
+0

わかりました。 TreeModelFilterについて心配することなく、TreeModelからすべてを理解することができます。そして、あなたは私のコードを整理しました!ありがとう、サラ。 – method

1

私はRubyについて何も知りませんが、このエラーは再帰反復が多すぎることを明確に示しています。万歳 - - コンテキストが原因と、各呼び出しのスタック上に保存する必要が

stack overflow

:-) は、反復のあなたのレベルを追跡し、エラーでそれをプリントアウトするために変数を追加します。あなたのデータや再帰ロジック、またはその両方に問題があります。

関連する問題