原文: https://zetcode.com/gfx/pycairo/shapesfills/

在 PyCairo 教程的这一部分中,我们创建一些基本的和更高级的形状。 我们用纯色,图案和渐变填充这些形状。 渐变将在单独的章节中介绍。

基本形状

PyCairo 有一些创建简单形状的基本方法。

  1. def on_draw(self, wid, cr):
  2. cr.set_source_rgb(0.6, 0.6, 0.6)
  3. cr.rectangle(20, 20, 120, 80)
  4. cr.rectangle(180, 20, 80, 80)
  5. cr.fill()
  6. cr.arc(330, 60, 40, 0, 2*math.pi)
  7. cr.fill()
  8. cr.arc(90, 160, 40, math.pi/4, math.pi)
  9. cr.fill()
  10. cr.translate(220, 180)
  11. cr.scale(1, 0.7)
  12. cr.arc(0, 0, 50, 0, 2*math.pi)
  13. cr.fill()

在此示例中,我们创建一个矩形,一个正方形,一个圆形,一个弧形和一个椭圆形。

  1. cr.rectangle(20, 20, 120, 80)
  2. cr.rectangle(180, 20, 80, 80)

rectangle()方法用于创建正方形和矩形。 正方形只是矩形的一种特定类型。 参数是窗口左上角的 x 和 y 坐标以及矩形的宽度和高度。

  1. cr.arc(330, 60, 40, 0, 2*math.pi)

arc()方法创建一个圆。 参数是弧度中心的 x 和 y 坐标,半径以及弧度的开始和结束角度。

  1. cr.arc(90, 160, 40, math.pi/4, math.pi)

在这里,我们画一条弧,是圆的一部分。

  1. cr.scale(1, 0.7)
  2. cr.arc(0, 0, 50, 0, 2*math.pi)

我们使用scale()arc()方法创建一个椭圆。

PyCairo 形状和填充 - 图1

图:基本形状

可以使用基本图元的组合来创建其他形状。

complex_shapes.py

  1. #!/usr/bin/python
  2. '''
  3. ZetCode PyCairo tutorial
  4. This code example draws another
  5. three shapes in PyCairo.
  6. Author: Jan Bodnar
  7. Website: zetcode.com
  8. Last edited: April 2016
  9. '''
  10. from gi.repository import Gtk
  11. import cairo
  12. class cv(object):
  13. points = (
  14. ( 0, 85 ),
  15. ( 75, 75 ),
  16. ( 100, 10 ),
  17. ( 125, 75 ),
  18. ( 200, 85 ),
  19. ( 150, 125 ),
  20. ( 160, 190 ),
  21. ( 100, 150 ),
  22. ( 40, 190 ),
  23. ( 50, 125 ),
  24. ( 0, 85 )
  25. )
  26. class Example(Gtk.Window):
  27. def __init__(self):
  28. super(Example, self).__init__()
  29. self.init_ui()
  30. def init_ui(self):
  31. darea = Gtk.DrawingArea()
  32. darea.connect("draw", self.on_draw)
  33. self.add(darea)
  34. self.set_title("Complex shapes")
  35. self.resize(460, 240)
  36. self.set_position(Gtk.WindowPosition.CENTER)
  37. self.connect("delete-event", Gtk.main_quit)
  38. self.show_all()
  39. def on_draw(self, wid, cr):
  40. cr.set_source_rgb(0.6, 0.6, 0.6)
  41. cr.set_line_width(1)
  42. for i in range(10):
  43. cr.line_to(cv.points[i][0], cv.points[i][1])
  44. cr.fill()
  45. cr.move_to(240, 40)
  46. cr.line_to(240, 160)
  47. cr.line_to(350, 160)
  48. cr.fill()
  49. cr.move_to(380, 40)
  50. cr.line_to(380, 160)
  51. cr.line_to(450, 160)
  52. cr.curve_to(440, 155, 380, 145, 380, 40)
  53. cr.fill()
  54. def main():
  55. app = Example()
  56. Gtk.main()
  57. if __name__ == "__main__":
  58. main()

在此示例中,我们创建一个星形对象,一个三角形和一个修改后的三角形。 这些对象是使用直线和一条曲线创建的。

  1. for i in range(10):
  2. cr.line_to(cv.points[i][0], cv.points[i][1])
  3. cr.fill()

通过连接点元组中的所有点来绘制星形。 fill()方法用当前颜色填充星形对象。

  1. cr.move_to(240, 40)
  2. cr.line_to(240, 160)
  3. cr.line_to(350, 160)
  4. cr.fill()

这些线创建一个三角形。 最后两点将自动合并。

  1. cr.move_to(380, 40)
  2. cr.line_to(380, 160)
  3. cr.line_to(450, 160)
  4. cr.curve_to(440, 155, 380, 145, 380, 40)
  5. cr.fill()

修改后的三角形是两条直线和一条曲线的简单组合。

PyCairo 形状和填充 - 图2

图:复杂形状

填充

填充填充形状的内部。 填充可以是纯色,图案或渐变。

纯色

颜色是代表红色,绿色和蓝色(RGB)强度值的组合的对象。 PyCairo 的有效 RGB 值在 0 到 1 的范围内。

  1. def on_draw(self, wid, cr):
  2. cr.set_source_rgb(0.2, 0.23, 0.9)
  3. cr.rectangle(10, 15, 90, 60)
  4. cr.fill()
  5. cr.set_source_rgb(0.9, 0.1, 0.1)
  6. cr.rectangle(130, 15, 90, 60)
  7. cr.fill()
  8. cr.set_source_rgb(0.4, 0.9, 0.4)
  9. cr.rectangle(250, 15, 90, 60)
  10. cr.fill()

在示例中,我们绘制了四个彩色矩形。

  1. cr.set_source_rgb(0.2, 0.23, 0.9)
  2. cr.rectangle(10, 15, 90, 60)
  3. cr.fill()

set_source_rgb()方法将源设置为不透明的颜色。 参数是红色,绿色,蓝色强度值。 通过调用fill()方法,该源用于填充矩形的内部。

PyCairo 形状和填充 - 图3

图:纯色

图案

图案是可以用于填充形状的复杂图形对象。

patterns.py

  1. #!/usr/bin/python
  2. '''
  3. ZetCode PyCairo tutorial
  4. This program shows how to work
  5. with patterns in PyCairo.
  6. Author: Jan Bodnar
  7. Website: zetcode.com
  8. Last edited: April 2016
  9. '''
  10. from gi.repository import Gtk
  11. import cairo
  12. class Example(Gtk.Window):
  13. def __init__(self):
  14. super(Example, self).__init__()
  15. self.init_ui()
  16. self.create_surpat()
  17. def init_ui(self):
  18. darea = Gtk.DrawingArea()
  19. darea.connect("draw", self.on_draw)
  20. self.add(darea)
  21. self.set_title("Patterns")
  22. self.resize(300, 290)
  23. self.set_position(Gtk.WindowPosition.CENTER)
  24. self.connect("delete-event", Gtk.main_quit)
  25. self.show_all()
  26. def create_surpat(self):
  27. sr1 = cairo.ImageSurface.create_from_png("blueweb.png")
  28. sr2 = cairo.ImageSurface.create_from_png("maple.png")
  29. sr3 = cairo.ImageSurface.create_from_png("crack.png")
  30. sr4 = cairo.ImageSurface.create_from_png("chocolate.png")
  31. self.pt1 = cairo.SurfacePattern(sr1)
  32. self.pt1.set_extend(cairo.EXTEND_REPEAT)
  33. self.pt2 = cairo.SurfacePattern(sr2)
  34. self.pt2.set_extend(cairo.EXTEND_REPEAT)
  35. self.pt3 = cairo.SurfacePattern(sr3)
  36. self.pt3.set_extend(cairo.EXTEND_REPEAT)
  37. self.pt4 = cairo.SurfacePattern(sr4)
  38. self.pt4.set_extend(cairo.EXTEND_REPEAT)
  39. def on_draw(self, wid, cr):
  40. cr.set_source(self.pt1)
  41. cr.rectangle(20, 20, 100, 100)
  42. cr.fill()
  43. cr.set_source(self.pt2)
  44. cr.rectangle(150, 20, 100, 100)
  45. cr.fill()
  46. cr.set_source(self.pt3)
  47. cr.rectangle(20, 140, 100, 100)
  48. cr.fill()
  49. cr.set_source(self.pt4)
  50. cr.rectangle(150, 140, 100, 100)
  51. cr.fill()
  52. def main():
  53. app = Example()
  54. Gtk.main()
  55. if __name__ == "__main__":
  56. main()

在此示例中,我们绘制了四个矩形。 这次我们用一些模式填充它们。 我们使用来自 Gimp 图像处理器的四个图案图像。 我们必须保留这些图案的原始大小,因为我们将它们平铺。

我们在draw()方法之外创建图像表面。 每次需要重新绘制窗口时,从硬盘读取数据都不会很有效。

  1. sr1 = cairo.ImageSurface.create_from_png("blueweb.png")

从 PNG 图像创建图像表面。

  1. self.pt1 = cairo.SurfacePattern(sr1)
  2. self.pt1.set_extend(cairo.EXTEND_REPEAT)

从表面创建图案。 我们将模式设置为cairo.EXTEND_REPEAT,这将导致图案通过重复平铺。

  1. cr.set_source(self.pt1)
  2. cr.rectangle(20, 20, 100, 100)
  3. cr.fill()

在这里,我们绘制第一个矩形。 set_source()方法告诉 Cairo 上下文使用图案作为绘图源。 图像图案可能不完全适合形状。 rectangle()创建一个矩形路径。 最后,fill()方法用源填充路径。

本章介绍了 PyCairo 的形状和填充。