Python 如何在绘图区域上绘制完整的图像表面?

Python 如何在绘图区域上绘制完整的图像表面?,python,gtk,cairo,imagesource,pycairo,Python,Gtk,Cairo,Imagesource,Pycairo,我正在开发Python+Gtk+Cairo应用程序。 我的应用程序需要绘制一些非常复杂(而且昂贵)的图形 出于性能原因,我首先在ImageSurface(屏幕外)上绘制,然后在DrawingArea对象上绘制ImageSurface内容 NB:我需要缩放/平移我的图纸,使其可见; 否则,大型图纸会从窗口掉出来 不幸的是,出现了一些问题:正如您所看到的,我无法绘制ImageSurface的全部内容。 通过使用“规范”上下文。设置源曲面(imageSurface、xCoord、yCoord) Con

我正在开发Python+Gtk+Cairo应用程序。 我的应用程序需要绘制一些非常复杂(而且昂贵)的图形

出于性能原因,我首先在ImageSurface(屏幕外)上绘制,然后在DrawingArea对象上绘制ImageSurface内容

NB:我需要缩放/平移我的图纸,使其可见; 否则,大型图纸会从窗口掉出来

不幸的是,出现了一些问题:正如您所看到的,我无法绘制ImageSurface的全部内容。 通过使用“规范”上下文。设置源曲面(imageSurface、xCoord、yCoord) Context.paint()

我只得到了错误的输出:

是我想要达到的结果:

如何强制绘制整个图像表面

下面是一个示例代码:

import gtk
import cairo

def main():
    w = gtk.Window()
    w.add(RubberTest())
    w.show_all()
    gtk.main()


class RubberTest(gtk.DrawingArea):
    def __init__(self, model=None):
        gtk.DrawingArea.__init__(self)
        self.set_size_request(800, 500)
        self.connect("expose-event", self._expose, self.create_basic_image())
        self.add_events(gtk.gdk.EXPOSURE_MASK
                      | gtk.gdk.BUTTON_PRESS_MASK
                      | gtk.gdk.BUTTON_RELEASE_MASK
                      | gtk.gdk.POINTER_MOTION_MASK)

    def create_basic_image(self):
        img = cairo.ImageSurface(cairo.FORMAT_ARGB32, 24, 24)
        cr = cairo.Context(img)

        # due to large coordinates, the drawing fall out of the window
        self.points = [(10000, 10000), (790000, 10000), (790000, 490000), (10000, 490000)]

        xMax, yMax, xMin, yMin = max([c[0] for c in self.points]), max([c[1] for c in self.points]), min([c[0] for c in self.points]), min([c[1] for c in self.points])
        maxRectWidth = xMax - xMin
        maxRectHeight = yMax - yMin

        w = 800
        h = 500
        width_ratio = float(w) / maxRectWidth
        height_ratio = float(h) / maxRectHeight

        # scale factor
        scaleFactor = min(height_ratio, width_ratio)

        cr.set_line_width(4)
        cr.set_source_rgb(1, 0, 0)

        cr.save()

        # scale + translate
        cr.scale(scaleFactor, scaleFactor)
        cr.translate(-xMin, -yMin)

        for i in range(0, len(self.points)):
            currPoint = self.points[i]
            currX = float(currPoint[0])
            currY = float(currPoint[1])
            nextIndex = i + 1
            if (nextIndex == len(self.points)):
                nextIndex = 0
            nextPoint = self.points[nextIndex]
            nextX = nextPoint[0]
            nextY = nextPoint[1]
            cr.move_to(currX, currY)
            cr.line_to(nextX, nextY)
        cr.restore()
        cr.close_path()
        cr.stroke_preserve()
        return img

    def _expose(self, sender, event, img):
        cr = self.window.cairo_create()
        cr.set_source_surface(img, 0, 0)
        cr.paint()
        return True

if __name__ == '__main__':
    main()
谢谢,
该代码创建了一个24x24大小的ImageSurface。该图像表面将完全显示。“缺少绘图”发生在绘制到此ImageSurface时,而不是在_expose()中。另外,为什么需要创建_basic_image()?你不能在_expose()中完成所有的绘图吗?非常感谢!!:-)我觉得这是个愚蠢的错误。是的,通常,我直接在expose()body中绘制所有内容;现在,由于绘图越来越复杂,有人建议我在屏幕外立即绘制任何东西。在expose()中,我限制将此ImageSource从内存复制到目标曲面,以避免耗时的重新计算和重画。这可能导致性能的提高。你能证实这一点吗?这取决于你的内容改变的频率和你必须重画的频率。然而,我认为GTK已经记住了你画的东西,所以这不会有多大帮助。您可以尝试将print(“foo”)添加到_expose()-函数中,以便在调用时看到它。我想你的ImageSurface帮不上忙。。。