为了我自己的利益和可能的教育用途,我想为 Python 和 Cairo 制作一个类似于 pygame 的 API。但我不希望它完全是 pygame。我想把它做成一个半静态的绘图平台,使用 GTK/GDK 显示一个或多个图像,我想模仿 TiKZ(乳胶包)的优秀 API 原理。PyGame API 还不错,但我并不满意。一个特别的问题是,我希望包通过将所有内容绘制到 pixbuf(使用 Cairo)来处理窗口刷新,并在窗口未发现时自动重绘 pixbuf。这样,最终程序员就不必担心窗口刷新。事实上,最终程序员不应该只需要编写一个类或函数,或者只需要编写一行代码就可以画出笑脸(比如说)。图形库也不必像在 TkInter 中那样维护更长的存储形状对象列表。(至少,我希望开罗不要这样做违背我的意图。)
我成功地在 pycairo 中绘制了各种东西,并输出到 ImageMagick 和 Postscript。所以我对 pycairo 本身没意见。
不幸的是,我找到的 cairo/gtk/pycairo/pygtk 文档 --- 我不知道它是为谁编写的,但不是为我编写的。目前,我是 Project Euler 类型的程序员,而不是“5 个最前沿的超面向对象 API”类型的程序员。我想看到一个关于做什么的清晰解释,和/或一个清晰的例子。
好的,我接受了发布的一个答案,因为它至少有点帮助。但简而言之,这是真正的重点。关键是当你在 GDK 中绘制东西时,GDK 会做一个临时的双缓冲,包括使用 Cairo。预计当您处理公开事件时,您将重绘所有内容。但是如果你有一个非常复杂的图像,这是一个缓慢的过程,尤其是在 Python 中。因此,如果开罗可以写信给永久居民,那就更好了双缓冲区而不是临时缓冲区,然后将使用 GDK 公开该永久双缓冲区。一些开发人员想要解决这个问题。似乎有某种解决方案的项目之一是 Google Chromium --- 你有没有注意到 Google Chrome 中的窗口曝光有多好,例如在 Linux 中?所以我将查看 Chromium 源代码,看看我是否可以轻松地做到这一点。
附录:我看到我确实通过专门提到“pixbufs”来混淆这个问题。我并不真正关心 pixbufs(我再次更改了问题标题)。我真正关心的是在 Cairo 和 GTK/GDK 之间创建一个永久的双缓冲像素阵列,而不是一个临时的双缓冲像素阵列。似乎最简单的方法是使 GTK 窗口成为 Cairo 曲面,并使双缓冲区成为另一个 Cairo 曲面。由于我在我的问题中要求提供样本,因此这里有一些:
class Canvas(gtk.DrawingArea):
def __init__(self):
super(Canvas, self).__init__()
self.connect("expose_event", self.expose)
self.set_size_request(width,height)
def expose(self, widget, event):
cr = widget.window.cairo_create()
cr.set_source_surface(mybuffer,0,0)
cr.paint()
另一个很快出现的棘手问题是,我希望这是一个 WYSISWYG 绘图环境,可以立即绘制 Python 要求它绘制的内容 --- 并且可以扩展到动画。但是,大多数 GTK 示例都不是这样设置的:事件处理被推迟到我调用gtk.main()
. (或者在 Python 中,我惊讶地发现它raw_input()
也以某种方式刷新了 GTK 事件队列。)我找到了一个很好的解释,带有 Python 示例,可以替代将事件控制权交给 GTK。最简单的解决方案也可能是我将采用的解决方案是,只要您想这样做,就可以使用它来刷新事件缓冲区:
while gtk.events_pending(): gtk.main_iteration(False)
我还需要最后一件事,刷新像素缓冲区和事件缓冲区。看起来这样做的一种方法是window.queue_draw()