Python + Cairo + GTK / GDK像素缓冲区的简单设置

时间:2011-10-20 01:27:23

标签: python pygtk pycairo

为了我自己的利益并可能用于教育用途,我想为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事件队列。)我发现a nice explanation,使用Python示例,可以选择向GTK提供事件控制。最简单的解决方案,也许我将采用的解决方案是在你想要的时候使用它来刷新事件缓冲区:

while gtk.events_pending(): gtk.main_iteration(False)

我需要最后一件事来刷新像素缓冲区以及事件缓冲区。看起来这样做的一种方法是window.queue_draw()

1 个答案:

答案 0 :(得分:2)

由于这个评论太大而无法发表评论,我已将此作为回应添加 问题不太清楚。你的意思是问如何使用cairo绘图来绘制到Gtk Widgets?首先,没有什么叫GTK Pixbuf,我想你指的是GDK Pixbuf。 GTK中的大多数绘图内容都是在GDK层完成的。如果您想了解窗口,绘图机制或图像处理,您应该查看GDK以获取更多详细信息。 These links有望帮助您了解有关cairo-gdk互动的一些见解。虽然我使用GTK,GDK和amp;的python绑定经验开罗是零,但我认为如果你查看gdk-cairo样本谷歌将为你提供一些很好的资源。
希望这至少有一点帮助!