代码之家  ›  专栏  ›  技术社区  ›  method

堆栈级别太深错误Ruby-Gnome2

  •  0
  • method  · 技术社区  · 17 年前

    我有一个带有Gtk::TreeModel和Gtk::TreeModelFilter的Gtk::TreeView。树模型如下所示:

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

    我想对@search_entry的内容进行筛选,但如果category1下的行仍然可见,我希望category1显示出来;如果category2下没有行仍然可见,我希望category2隐藏起来。我对Gtk::TreeModelFilter#set#u visible_func的理解是从“子模型”中获取模型和iter,以便检查是否显示子iter。每次我调用Gtk::TreeModelFilter#RefFilter时,模型中的每个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
    

    导致每个iter的“此错误:堆栈级别太深”输出。

    2 回复  |  直到 17 年前
        1
  •  1
  •   cdonner    17 年前

    我对Ruby一无所知,但这个错误显然指向了太多的递归迭代。每次调用都需要将上下文存储在堆栈上,导致-hurray-a

    堆栈溢出

    添加一个变量来跟踪迭代的级别,并打印出错误。数据或递归逻辑有问题,或者两者都有问题。

        2
  •  1
  •   Sarah Mei    17 年前

    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 
    
    推荐文章