3

我正在使用 pygtk 为 Maemo 平台编写应用程序,树视图的渲染速度似乎是个问题。由于该应用程序是一个媒体控制器,因此我在 UI 中使用了过渡动画。这些动画在 UI 中移动时将控件滑入视图。树控件的问题是它很慢。

只是在屏幕中间移动小部件并没有那么慢,但如果单元格被暴露,帧率真的会下降。更烦人的是,如果唯一暴露的区域是带有行标签的标题行,那么帧率仍然受到控制。

由此判断,我怀疑每次曝光单行像素时,GTK 树视图都会再次绘制完整的单元格。有没有办法以某种方式强制 GTK 将整个小部件绘制到某个缓冲区中,即使它的一部分不在屏幕上,然后在制作动画时使用缓冲区来绘制小部件?

使用视口和向上滚动以及使用布局面板和向下移动小部件之间也有区别吗?我本以为 Viewport 会更快,但是当我尝试这两个版本时,我并没有发现真正的区别。

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

4

1 回答 1

1

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

在 PyGTK 中,您可以使用gtk.GenericCellRenderer. 在您的装饰器单元渲染器中,当要求渲染时执行以下操作:

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

最后一步还意味着在第一次渲染单元格时缓存确实会产生开销。通过使用缓存策略可以稍微缓解这个问题。您可能想根据渲染值的分布尝试不同的事情:

  • 如果所有单元格都是唯一的,那么除了将所有内容缓存到某个限制或某些 MRU 策略之外,没有什么可做的
  • 如果您有某种Zipf 分布,即某些单元格非常常见,而其他单元格非常罕见,您应该只缓存高频单元格并摆脱稀有单元格值的缓存开销。

话虽如此,我不能说它是否会有所作为。我从一个有点类似的问题中获得的经验是,任何涉及文本的内容通常都很慢,以至于缓存是有意义的——抱歉,我不能给出更简单的建议。

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

于 2009-07-15T22:29:10.687 回答