代码之家  ›  专栏  ›  技术社区  ›  Mikko Rantanen

加速gtk树视图

  •  3
  • Mikko Rantanen  · 技术社区  · 17 年前

    我正在使用pygtk为maemo平台编写一个应用程序,树视图的呈现速度似乎是个问题。因为应用程序是媒体控制器,所以我在ui中使用转换动画。这些动画在用户界面周围移动时将控件滑入视图。树控件的问题是速度慢。

    仅仅在屏幕中间移动小部件并没有那么慢,但是如果单元格暴露在外,帧速率就会下降。更让人恼火的是,如果唯一暴露的区域是带有行标签的标题行,那么帧速率将保持在控制之下。

    由此判断,我怀疑gtk树视图每次暴露一行像素时都会再次绘制完整的单元格。有没有办法强迫gtk将整个小部件绘制到某个缓冲区中,即使其中的一部分在屏幕外,然后在动画制作时使用缓冲区绘制小部件?

    使用viewport和向上滚动viewport和使用layout panel以及向下移动widgets之间有区别吗?我本以为viewport更快,但当我尝试两个版本时,我没有看到真正的区别。

    我知道这不一定是GTK的目的。我尝试过的另一种方法是pygame,但我更喜欢一些更高级别的实现,其中内置了基于小部件的事件处理。pygtk还具有在windows和窗口中运行的优点,因此开发更容易。

    1 回复  |  直到 17 年前
        1
  •  1
  •   Torsten Marek    17 年前

    我从来没有这样做,但你可以尝试实现缓存自己。不要使用预定义的单元呈现器,而是实现自己的单元呈现器(可能作为实际的单元呈现器的包装器),但是缓存pixmap。

    在PyGTK,你可以使用 gtk.GenericCellRenderer . 在decorator单元格呈现程序中,在要求呈现时执行以下操作:

    • 保存一个屏幕外像素的缓存(或者更好,只有一个大像素)和一个大小的缓存
    • 如果要求预测大小或渲染,请从相关属性创建键
    • 如果密钥存在于缓存中,请使用缓存的pixmap,将缓存的pixmap放到给定的drawable上。
    • 否则,首先让实际的单元渲染器完成工作,然后复制它

    最后一步还意味着缓存在第一次呈现单元格时确实会产生开销。这个问题可以通过使用缓存策略来减轻。根据渲染值的分布,您可能需要尝试不同的方法:

    • 如果所有的单元都是唯一的,那么除了将所有内容缓存到某个限制或某个mru策略之外,就没什么可做的了。
    • 如果你有某种 Zipf distribution ,也就是说,有些单元格非常常见,而另一些单元格则非常罕见,您应该只高速缓存这些单元格,而不必为很少的单元格值花费缓存开销。

    话虽如此,我不能说这会不会有什么不同。我从一个类似的问题中得到的经验是,涉及文本的任何事情通常都很慢,以至于缓存是有意义的,抱歉我不能给出更简单的建议。

    在尝试之前,您还可以简单地编写一个装饰单元呈现器,它只计算实际呈现单元的频率,并获取一些计时信息,以便您了解热点在哪里,以及缓存这些值是否有任何意义。