2009-03-04 64 views
0

我有一個Gtk :: TreeView與一個Gtk :: TreeModel和一個Gtk :: TreeModelFilter。神木模式是這樣的:堆棧級別太深錯誤Ruby-Gnome2

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

我想在@search_entry的內容進行篩選,但我想,如果在它之下的行仍然可見要顯示類別1,類別2和被隱藏如果沒有它下面的行仍然可見。我對Gtk :: TreeModelFilter#set_visible_func的理解是,你從「子模型」中獲得了模型和iter,以便檢查是否顯示iter。每次調用Gtk :: TreeModelFilter#refilter時,都會調用此函數。因此,我說:如果您剛纔給我的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 

導致一個 「這樣的錯誤:堆棧級別太深」 輸出爲每個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

好的,我明白了。我們可以從TreeModel中找出所有的東西,而不用擔心TreeModelFilter。你清理了我的代碼!謝謝,莎拉。 – method 2009-03-08 02:07:23

1

我對Ruby一無所知,但是這個錯誤清楚地指向了太多的遞歸迭代。上下文需要被存儲在堆棧每次調用上,造成 - 華友世紀 - 一個

stack overflow

:-) 添加一個變量來跟蹤你的迭代的水平,並與錯誤打印出來。數據或遞歸邏輯或者有問題,或者兩者都有。

相關問題