スタックレベルの深すぎるエラーRuby-Gnome2
-
03-07-2019 - |
質問
Gtk :: TreeModelとGtk :: TreeModelFilterを備えたGtk :: TreeViewがあります。ツリーモデルは次のようになります。
category1
--> actual row of data
category2
--> actual row of data
@search_entryのコンテンツをフィルタリングしたいのですが、その下の行がまだ表示されている場合はcategory1を表示し、その下にまだ行がない場合はcategory2を非表示にします。 Gtk :: TreeModelFilter#set_visible_funcについての私の理解は、「子モデル」からモデルとiterを取得し、子iterを表示するかどうかを確認できるということです。この関数は、Gtk :: TreeModelFilter#refilterを呼び出すたびにモデルのすべてのiterで呼び出されます。したがって、私が言っているのは、先ほど与えたiterが最初のレベルにある場合、パスを取得し、1つ下に移動し、変換しますフィルタのモデル上の同じパスを使用し、可視性をテストするために新しいパスが存在するかどうかを使用します。
@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
他のヒント
Rubyについては何も知りませんが、このエラーは明らかに反復の繰り返しが多すぎることを示しています。コンテキストは、呼び出しごとにスタックに保存する必要があり、原因は-hurray-a
スタックオーバーフロー
:-) 反復のレベルを追跡する変数を追加し、エラーとともに出力します。データまたは再帰ロジック、あるいはその両方に問題があります。