PyCairo 中的基本绘图
在 PyCairo 教程中的这个部分,我们将会绘制一些基本的元素。我们将绘制简单的直线,应用填充和 stroke 操作,我们将会讨论虚线,线帽和线的交合。
直线
直线是非常基本的向量对象。为了绘制一条直线,我们使用两个方法调用。一个是move_to()调用,我们需要把起点位置传给它。另一个是line_to(),我们则需要把直线的终点传给它。
#!/usr/bin/python
'''
ZetCode PyCairo tutorialIn this program, we connect all mouse
clicks with a line.author: Jan Bodnar
website: zetcode.com
last edited: August 2012
'''import gtk
import cairoclass MouseButtons:LEFT_BUTTON = 1RIGHT_BUTTON = 3class MainWindow(gtk.Window):def __init__(self):super(self.__class__, self).__init__()self.init_ui()print "MainWindow: " + str(self)def init_ui(self):self.darea = gtk.DrawingArea()self.darea.connect("expose_event", self.expose)self.darea.set_events(gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON_RELEASE_MASK)self.add(self.darea)self.coords = []self.darea.connect("button-press-event", self.on_button_press)self.set_title("Lines")self.resize(300, 200)self.set_position(gtk.WIN_POS_CENTER)self.connect("delete-event", gtk.main_quit)self.show_all()def on_button_press(self, widget, event):if event.type == gtk.gdk.BUTTON_PRESS and event.button == MouseButtons.LEFT_BUTTON:self.coords.append([event.x, event.y])if event.type == gtk.gdk.BUTTON_PRESS and event.button == MouseButtons.RIGHT_BUTTON:self.darea.queue_draw()passdef expose(self, widget, event):self.context = widget.window.cairo_create()self.on_draw(300, self.context)def on_draw(self, wid, cr):cr.set_source_rgb(0, 0, 0)cr.set_line_width(0.5)for i in self.coords:for j in self.coords:cr.move_to (i[0], i[1])cr.line_to (j[0], j[1])cr.stroke()del self.coords[:]def main():window = MainWindow()gtk.main()if __name__ == "__main__":main()
在我们的例子中,我们用鼠标左键随机的在窗口中点击。每一次点击的位置都会被存进一个列表。当我们在窗口中按下鼠标右键时,列表中每一个点都会与其他所有的点连接起来。通过这种方式,我们可以创建一些有趣的对象。再次点击鼠标右键可以清空窗口,我们就可以创建另一个对象了。
class MouseButtons:LEFT_BUTTON = 1RIGHT_BUTTON = 3
GTK 文档简单的状态标记,鼠标左键为数字1,鼠标右键为数字3。我们创建一个定制的类来为鼠标的键做标识。
self.darea.set_events(gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON_RELEASE_MASK)
某些事件默认情况下是不打开的。鼠标按钮按下事件即属其中。然而,我们需要打开鼠标按钮按下事件。
self.darea.connect("button-press-event", self.on_button_press)
在这个例子中,我们对鼠标按下事件作出反应。
cr.set_source_rgb(0, 0, 0)cr.set_line_width(0.5)
将用黑色墨水和0.5点宽度来画直线。
for i in self.coords:for j in self.coords:cr.move_to (i[0], i[1])cr.line_to (j[0], j[1])cr.stroke()
我们把列表中每一个点连接到其他的每一个点。stroke()调用绘制直线。
del self.coords[:]
最后,所有的坐标被删除。现在我们可以创建另一个对象了。
def on_button_press(self, widget, event):if event.type == gtk.gdk.BUTTON_PRESS and event.button == MouseButtons.LEFT_BUTTON:self.coords.append([event.x, event.y])
如果按下了鼠标左按钮,我们会把它的x,y坐标添加到self.coords列表中去。
if event.type == gtk.gdk.BUTTON_PRESS and event.button == MouseButtons.RIGHT_BUTTON:self.darea.queue_draw()
按下鼠标右键时,我们调用queue_draw()方法,它将会渲染绘制区域。所有的点会连成线。
Figure: Lines
填充和stroke
Stroke操作绘制形状的轮廓,而填充操作则填充形状的内部。
#!/usr/bin/python
'''
ZetCode PyCairo tutorialThis code example draws a circle
using the PyCairo libraryauthor: Jan Bodnar
website: zetcode.com
last edited: August 2012
'''import cairo
import gtk
import mathclass 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("Fill & stroke")self.resize(230, 150)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(230, self.context)def on_draw(self, wid, cr):cr.set_line_width(9)cr.set_source_rgb(0.7, 0.2, 0.0)width, height = self.get_size()cr.translate(width/2, height/2)cr.arc(0, 0, 50, 0, 2 * math.pi)cr.stroke_preserve()cr.set_source_rgb(0.3, 0.4, 0.6)cr.fill()def main():window = MainWindow()gtk.main()if __name__ == "__main__":main()
在我们的例子中,我们将画一个圆圈,然后用一种颜色填充它。
import math
pi常量需要这个模块,后面在绘制圆圈时会用到pi。
cr.set_line_width(9)cr.set_source_rgb(0.7, 0.2, 0.0)
我们用set_line_width()方法设置线的宽度。我们使用set_source_rgb()把source设为某种暗红色。
width, height = self.get_size()
此处我们获取窗口的宽度和高度。我们需要这些值来将圆圈放到窗口的中心位置。
cr.translate(width/2, height/2)cr.arc(0, 0, 50, 0, 2 * math.pi)cr.stroke_preserve()
通过translate()方法,我们将绘制的原点移动到窗口的中心位置。我们想要将我们的圆圈放在中心位置。arc()方法向cairo绘制上下文中添加一个新的圆圈的path。最后,stroke_preserve()方法绘制圆圈的轮廓。不像stroke()方法,它会保留形状以用于后面的绘制。
cr.set_source_rgb(0.3, 0.4, 0.6)cr.fill()
我们换一种颜色来画,使用fill()方法并用一种新的颜色来填充圆圈。
Figure: Fill & stroke
Pen dashes
每一条直线都可以用不同的pen dash来画。一个pen dash定义了直线的style。dash模式由set_dash()方法指定。模式由一个浮点值组成的dash列表来描述。它们设置了dash模式的on和off部分。dash被stroke()方法用来创建一条直线。如果dashes的数量为0,则dashing是被关掉的。如果dashes的数量为1,则假设是一个对称的模式,其中on和off部分交替出现,它们的大小由dashes中的那个值来指定。
def on_draw(self, wid, cr):cr.set_source_rgba(0, 0, 0, 1)cr.set_line_width(2)cr.set_dash([4.0, 21.0, 2.0])cr.move_to(40, 30)cr.line_to(250, 30)cr.stroke()cr.set_dash([14.0, 6.0])cr.move_to(40, 50)cr.line_to(250, 50)cr.stroke()cr.set_dash([1.0])cr.move_to(40, 70)cr.line_to(250, 70)cr.stroke()
我们用三种不同类型的pen dashes画了三条直线。
cr.set_dash([4.0, 21.0, 2.0])
我们定义了具有三个数字的模式。我们画4个点,21个不画,然后2个点画。接下来是4个点不画,21个点画和2个点不画。这个模式如此交替,直到直线的终点。
cr.set_dash([14.0, 6.0])
在这个模式中,我们总是让14个点画,6个不画。
cr.set_dash([1.0])
我们在这儿创建了一个对称的pen dash模式,交替的一个点画,一个点不画。
Figure: Pen dashes
Line caps
Line caps 是直线的终点。
- cairo.LINE_CAP_BUTT
- cairo.LINE_CAP_ROUND
- cairo.LINE_CAP_SQUARE
Cairo中有三种不同的line cap style。
Figure: Square, round and butt caps
相对于具有一个cairo.LINE_CAP_BUTT cap的直线,具有一个cairo.LINE_CAP_SQUARE cap的直线将有不一样的大小。如果一条直线x单元宽,具有一个cairo.LINE_CAP_SQUARE cap的直线将会要大整整x个单元。开始处x/2个单元,结尾处x/2个单元。
def on_draw(self, wid, cr):cr.set_source_rgba(0, 0, 0, 1)cr.set_line_width(12)cr.set_line_cap(cairo.LINE_CAP_BUTT)cr.move_to(30, 50)cr.line_to(150, 50)cr.stroke()cr.set_line_cap(cairo.LINE_CAP_ROUND)cr.move_to(30, 90)cr.line_to(150, 90)cr.stroke()cr.set_line_cap(cairo.LINE_CAP_SQUARE)cr.move_to(30, 130)cr.line_to(150, 130)cr.stroke()cr.set_line_width(1.5)cr.move_to(30, 35)cr.line_to(30, 145)cr.stroke()cr.move_to(150, 35)cr.line_to(150, 145)cr.stroke()cr.move_to(155, 35)cr.line_to(155, 145)cr.stroke()
这个例子画了三条具有不同的line caps的直线。它也通过画三条额外的垂直方向的细线生动的演示了直线不同大小的影响。
cr.set_line_width(12)
我们的直线将是12个单元宽的。默认的直线宽度为2.
cr.set_line_cap(cairo.LINE_CAP_ROUND)cr.move_to(30, 90)cr.line_to(150, 90)cr.stroke()
此处我们画了一条具有一个cairo.LINE_CAP_ROUND cap的水平直线。
cr.set_line_width(1.5)cr.move_to(30, 35)cr.line_to(30, 145)cr.stroke()
这是用于演示不同直线大小的影响的三条垂直直线之一。
Figure: Line caps
Line joins
直线可以用三种不同的联合style来做联合。
- cairo.LINE_JOIN_MITER
- cairo.LINE_JOIN_BEVEL
- cairo.LINE_JOIN_ROUND
Figure: Bevel, Round, Miter line joins
def on_draw(self, wid, cr):cr.set_line_width(14)cr.rectangle(30, 30, 100, 100)cr.set_line_join(cairo.LINE_JOIN_MITER)cr.stroke()cr.rectangle(160, 30, 100, 100)cr.set_line_join(cairo.LINE_JOIN_BEVEL)cr.stroke()cr.rectangle(100, 160, 100, 100)cr.set_line_join(cairo.LINE_JOIN_ROUND)cr.stroke()
在这个例子中,我们画了三个具有不同的线联合的厚矩形。
cr.set_line_width(14)
直线是14个单元宽的。
cr.rectangle(30, 30, 100, 100)cr.set_line_join(cairo.LINE_JOIN_MITER)cr.stroke()
此处我们画了一个有着 cairo.LINE_JOIN_MITER联合风格的矩形。
Figure: Line joins
PyCairo指南的这一章中,我们做了一些基本的绘图。
原文
Done.
PyCairo 中的基本绘图相关推荐
- MFC中的GDI绘图
MFC中的GDI绘图 目录(?)[+] 什么是GDI 什么是DC MFC中与GDI有关的类 获取设备环境 设置坐标映射 创建绘图工具并选入DC 调用DC绘图函数绘图 三坐标映射实例 一.关于GDI的基 ...
- PyCairo 中的图片
PyCairo 教程的这个部分,我们将讨论图片.我们将演示如何在 GTK 窗口中显示一幅 PNG 或JPEG 图片.我们也将在图片上绘制一些文字. 显示一幅 PNG 图片 在第一个例子中,我们将显示一 ...
- PyCairo 中的文本
PyCairo 教程的这个部分,我们将与文本打交道. 灵魂伴侣 在第一个例子中,我们将在窗口中显示一些歌词. def on_draw(self, wid, cr):cr.set_source_rgb( ...
- PyCairo 中的剪裁和屏蔽
在 PyCairo 教程的这个部分,我们将讨论剪裁和屏蔽操作. 剪裁 裁剪 是将绘制限定在某一区域内.这样做有一些效率的因素,或者为了创建有趣的效果.PyCairo 有一个 clip() 方法用于设置 ...
- 数据科学 IPython 笔记本 8.15 Matplotlib 中的三维绘图
8.15 Matplotlib 中的三维绘图 原文:Three-Dimensional Plotting in Matplotlib 译者:飞龙 协议:CC BY-NC-SA 4.0 本节是<P ...
- opengl png图片 qt_QT中使用OpenGL绘图
在之前说道过VS2010中配合OpenGL绘图的问题,这回是想要说说在QT中使用OpenGL,其实两者并无太大区别,因为都是基于C++语言的. 主要是想简要介绍下OpenGL在QT中的使用方法跟一些错 ...
- VC++6.0中使用GDI+绘图(转载)
VC++6.0中使用GDI+绘图 1.在VC++6.0中配置GDI+环境 1.1 下载GDI+库 VC++6.0中没有GDI+库.可以从http://www.crazy-bit.com/downloa ...
- PS2: 这篇文章中的图片绘图工具使用的是Dia (sudo apt-get install dia)。据说yEd也很不错。...
SBCL编译过程 - O.Nixie的专栏 - 博客频道 - CSDN.NET PS2: 这篇文章中的图片绘图工具使用的是Dia (sudo apt-get install dia).据说yEd也很不 ...
- ai中画板脱离绘图区域_AI让您脱离舒适区
ai中画板脱离绘图区域 So much in our lives is driven by things we cannot explain, why should AI be any differe ...
最新文章
- cocos2dx-2.2.0的开始
- matlab傅里叶变换矩阵
- The number of object passed must be even but was [1]
- 9.C++弱引用智能指针weak_ptr的用处
- PyTorch 和 Tensorflow 学哪个?上手简单的PyTorch考虑一下!
- MATLAB中求矩阵非零元的坐标
- 【数论】疯狂 LCM(P1891)
- Leetcode--全排列(Java)
- 为什么雷军指责“华为不懂研发”?
- 数据库的备份 mysql
- 加快linux编译速度,Linux Makefile 编译速度的优化【转】
- CSS 奇技淫巧:动态高度过渡动画
- oracle安装gcc报错,记录oracle 9i for linux安装过程中几个错误
- 2021-2025年中国电子液体处理系统行业市场供需与战略研究报告
- Java分布式锁的概念以及使用优点
- datatable中某一列最小值_操作dom获取datatable中的某一行的某一列的数据
- 刷新报表页面的方法总结
- 《码出高效-JAVA开发手册》
- 安装SQL Sever2017时出现“Polybase要求安装Oracle JRE 7更新51(64位)或更高版本规则失效”的解决办法
- Scratch可以参加的编程比赛大全
热门文章
- Redis与Zookeeper实现分布式锁区别
- dhcp是哪一层的协议_OSI各个分层分别负责哪些功能?有哪些主要协议?涉及到哪些设备?...
- python程序文件扩展名有_python程序文件的扩展名称是什么
- 计算机与人力资源管理论文,人力资源管理专业计算机能力培养模式论文
- linux-Centos7安装python3并与python2共存
- PostgreSQL 与 MySQL 常用命令对照
- 关于使用fastjson统一序列化响应格式。
- 从“美屋”到“打扮家”:线下VR家居馆中的科技新体验
- 国内传感器市场也许正处在最好的时候
- Lync在Internet上无法登录问题之一