PyCairo指南的这个部分,我们将创建一些基本的和更高级的形状。我们将使用单一颜色,patterns和渐变来填充他们。渐变将在另一章中讨论。
PyCairo有一些基本的方法可以用来画简单的形状。
def on_draw(self, wid, cr): cr.set_source_rgb(0.6, 0.6, 0.6) cr.rectangle(20, 20, 120, 80) cr.rectangle(180, 20, 80, 80) cr.fill() cr.arc(330, 60, 40, 0, 2 * math.pi) cr.fill() cr.arc(90, 160, 40,math.pi/4, math.pi) cr.fill() cr.translate(220, 180) cr.scale(1, 0.7) cr.arc(0, 0, 50, 0, 2 * math.pi) cr.fill()
在这个例子中,我们将创建一个矩形,一个方形,一个圆形,一个弧形,和一个椭圆形。
cr.rectangle(20, 20, 120, 80) cr.rectangle(180, 20, 80, 80)
rectangle()方法用于创建方形和矩形。一个方形就仅仅是一个特殊的矩形。
cr.arc(330, 60, 40, 0, 2 * math.pi)
这一行创建一个圆形。
cr.arc(90, 160, 40,math.pi/4, math.pi)
这里我们创建一个弧形,一个圆形的一部分而已。
cr.scale(1, 0.7) cr.arc(0, 0, 50, 0, 2 * math.pi)
我们使用scale()和arc()方法来创建椭圆形。
Figure: Basic Shapes
其他的形状可以通过将基本的元素结合起来的方式创建。
#!/usr/bin/python ''' ZetCode PyCairo tutorial This code example draws another three shapes in PyCairo author: Jan Bodnar website: zetcode.com last edited: August 2012 ''' import cairo import gtk class cv(object): points = ( (0, 85), (75, 75), (100, 10), (125, 75), (200, 85), (150, 125), (160, 190), (100, 150), (40, 190), (50, 125), (0, 85) ) class MainWindow(gtk.Window): def __init__(self): super(self.__class__, self).__init__() self.init_ui() def init_ui(self): self.darea = gtk.DrawingArea() self.darea.connect("expose_event", self.expose) self.add(self.darea) self.set_title("Complex shapes") self.resize(480, 240) self.set_position(gtk.WIN_POS_CENTER) self.connect("delete-event", gtk.main_quit) self.show_all() def expose(self, widget, event): self.context = widget.window.cairo_create() self.on_draw(480, self.context) def on_draw(self, wid, cr): cr.set_source_rgb(0.6, 0.6, 0.6) cr.set_line_width(1) for i in range(10): cr.line_to(cv.points[i][0], cv.points[i][1]) cr.fill() cr.move_to(240, 40) cr.line_to(240, 160) cr.line_to(350, 160) cr.fill() cr.move_to(380, 40) cr.line_to(380, 160) cr.line_to(450, 160) cr.curve_to(440, 155, 380, 145, 380, 40) cr.fill() def main(): window = MainWindow() gtk.main() if __name__ == "__main__": main()
这个例子中,我们创建了一个五角星对象,一个三角形和一个改良的三角形。这些对象使用一些直线和一条曲线创建。
for i in range(10): cr.line_to(cv.points[i][0], cv.points[i][1]) cr.fill()
五角星通过交合点的元组中所有的点来画。fill()方法使用当前色彩填充五角星对象。
cr.move_to(240, 40) cr.line_to(240, 160) cr.line_to(350, 160) cr.fill()
这些线创建一个三角形。最后两个点由PyCairo自动的连接起来。
cr.move_to(380, 40) cr.line_to(380, 160) cr.line_to(450, 160) cr.curve_to(440, 155, 380, 145, 380, 40) cr.fill()
改良的三角形是两条直线和一条曲线的简单的结合。
Figure: Complex shapes
一个颜色是一个结合了红,绿和蓝(RGB)亮度的对象。PyCairo有效的RGB值在0到1范围内。
def on_draw(self, wid, cr): cr.set_source_rgb(0.2, 0.23, 0.9) cr.rectangle(10, 15, 90, 60) cr.fill() cr.set_source_rgb(0.9, 0.1, 0.1) cr.rectangle(130, 15, 90, 60) cr.fill() cr.set_source_rgb(0.4, 0.9, 0.4) cr.rectangle(250, 15, 90, 60) cr.fill()
在这个例子中,我们画了三个彩色的矩形。
cr.set_source_rgb(0.2, 0.23, 0.9) cr.rectangle(10, 15, 90, 60) cr.fill()
set_source_rgb()方法设置source为一个不透明的颜色。参数为红,绿,蓝亮度值。通过调用fill()方法,source被用于填充矩形的内部。
Figure: Solid colors
Patterns是复杂的可用于填充形状的图像对象。
#!/usr/bin/python ''' ZetCode PyCairo tutorial This program shows how to work with patterns in PyCairo author: Jan Bodnar website: zetcode.com last edited: August 2012 ''' import cairo import gtk class MainWindow(gtk.Window): def __init__(self): super(self.__class__, self).__init__() self.init_ui() self.create_surpat() def init_ui(self): self.darea = gtk.DrawingArea() self.darea.connect("expose_event", self.expose) self.add(self.darea) self.set_title("Patterns") self.resize(300, 290) self.set_position(gtk.WIN_POS_CENTER) self.connect("delete-event", gtk.main_quit) self.show_all() def create_surpat(self): sr1 = cairo.ImageSurface.create_from_png("blueweb.png") sr2 = cairo.ImageSurface.create_from_png("maple.png") sr3 = cairo.ImageSurface.create_from_png("crack.png") sr4 = cairo.ImageSurface.create_from_png("chocolate.png") self.pt1 = cairo.SurfacePattern(sr1) self.pt1.set_extend(cairo.EXTEND_REPEAT) self.pt2 = cairo.SurfacePattern(sr2) self.pt2.set_extend(cairo.EXTEND_REPEAT) self.pt3 = cairo.SurfacePattern(sr3) self.pt3.set_extend(cairo.EXTEND_REPEAT) self.pt4 = cairo.SurfacePattern(sr4) self.pt4.set_extend(cairo.EXTEND_REPEAT) def expose(self, widget, event): self.context = widget.window.cairo_create() self.on_draw(300, self.context) def on_draw(self, wdith, cr): cr.set_source(self.pt1) cr.rectangle(20, 20, 100, 100) cr.fill() cr.set_source(self.pt2) cr.rectangle(150, 20, 100, 100) cr.fill() cr.set_source(self.pt3) cr.rectangle(20, 140, 100, 100) cr.fill() cr.set_source(self.pt4) cr.rectangle(150, 140, 100, 100) cr.fill() def main(): window = MainWindow() gtk.main() if __name__ == "__main__": main()
在这个例子中,我们画了四个矩形。这次我们用一些patterns来填充它们。我们使用了来自于Gimp图像管理程序的四个patterns图像。我们必须保持那些patterns的原始大小,因为我们将要展开他们。
我们在draw()方法外面创建图像surface。每次窗口需要重画的时候,都从硬盘来读取是非常没有效率的。
sr1 = cairo.ImageSurface.create_from_png("blueweb.png")用一幅PNG图像创建一个图像surface。
self.pt1 = cairo.SurfacePattern(sr1) self.pt1.set_extend(cairo.EXTEND_REPEAT)由surface创建一个pattern。我们设置风格为 cairo.EXTEND_REPEAT,这将使得pattern以重复的方式展开。
cr.set_source(self.pt1) cr.rectangle(20, 20, 100, 100) cr.fill()
此处我们绘制我们的第一个矩形。set_source()方法告诉Cairo上下文,在画的时候,使用一个pattern作为一个source。图像模式可能不完全适合那个形状。rectangle()创建一个矩形的path。最后,fill()方法用source来填充path。
上面的那段code中所用到的四幅图片。
blueweb.png chocolate.png crack.png maple.png
上面那段code,执行的结果。
本章中我们讨论了PyCairo的形状和填充。