绘图区构件和绘图@GTK+ 2.0 中文教程连载
2010-12-21 16:28
316 查看
绘图区构件和绘图
现在,我们开始向屏幕绘图。我们使用的构件是绘图区构件。一个绘图区构件本质上是一个 X 窗口,没有其它的东西。它是一个空白的画布,我们可以在其上绘制需要的东西。一个绘图区构件用如下函数创建:GtkWidget* gtk_drawing_area_new (void); |
void gtk_drawing_area_size (GtkDrawingArea *darea, gint width, gint height); |
或用户手动调整包含绘图区的窗口的大小时,默认大小可以无效,这对所有的构件都是一样的。
当我们创建绘图区构件时应该注意,我们完全
负责绘制其上的内容。如果我们的窗口被遮住后暴露出来,我们得到一个暴露事件,我们必须重绘先前被遮住的部分。
为了能正确的重绘,我们必须记住绘制在屏幕上的内容。另外,这显然很麻烦,如果窗口的一部分被清除了,我们需一步步的重绘。解决的办法是使用一个后端位图
。我们用向图像中绘制来代替直接向屏幕绘制,当图像改变或图像的一部分需要显示,我们复制相应的部分到屏幕上。
用如下函数创建后端位图:
GdkPixmap* gdk_pixmap_new (GdkWindow *window, gint width, gint height, gint depth); |
参数设置一个 GDK 窗口,位图继承该窗口的所有属性。width
和height
设置位图的大小。depth
设置颜色深度
,那是每个象素的二进制位数,如果depth设为-1
,它会自动匹配窗口的颜色深度。
我们在事件"configure_event"的处理函数中创建位图。这个事件会在我们改变窗口大小时产生,包括窗口创建时。
/* 绘制区的后端位图 */ static GdkPixmap *pixmap = NULL; /* 创建一个适当大小的后端位图 */ static gint configure_event (GtkWidget *widget, GdkEventConfigure *event) { if (pixmap) gdk_pixmap_unref(pixmap); pixmap = gdk_pixmap_new(widget->window, widget->allocation.width, widget->allocation.height, -1); gdk_draw_rectangle (pixmap, widget->style->white_gc, TRUE, 0, 0, widget->allocation.width, widget->allocation.height); return TRUE; } |
清除位图,并初始化为白色。后面我们会详细讲解。
我们的暴露事件处理函数只是简单复制相应部分的位图到屏幕上(用暴露事件的event->area来确定重绘区域):
/* 从后端位图重新绘制屏幕 */ static gint expose_event (GtkWidget *widget, GdkEventExpose *event) { gdk_draw_pixmap(widget->window, widget->style->fg_gc[GTK_WIDGET_STATE (widget)], pixmap, event->area.x, event->area.y, event->area.x, event->area.y, event->area.width, event->area.height); return FALSE; } |
绘图。可绘区域可以是窗口、位图或黑白图。在上面我们已经见到了两个,gdk_draw_rectangle()
和gdk_draw_pixmap()
。这些函数的完全列表如下:
gdk_draw_line () gdk_draw_rectangle () gdk_draw_arc () gdk_draw_polygon () gdk_draw_string () gdk_draw_text () gdk_draw_pixmap () gdk_draw_bitmap () gdk_draw_image () gdk_draw_points () gdk_draw_segments () |
。这些函数的头两个参数都相同。第一个参数是可绘区域。第二个参数是图像关联
(GC)。
一
个图像关联封装一些信息,如前景色、背景色和线宽。GDK有一组函数用于创建和修改图像关联,但为了方便,我们仅使用预定义的图像关联。每个构件有一个相
关联的风格。(可以在 gtkrc 文件中修改,详见 GTK 的 rc 文件)其中,存储了许多图像关联。一些访问这些图像 关联的示例如下:
widget->style->white_gc widget->style->black_gc widget->style->fg_gc[GTK_STATE_NORMAL] widget->style->bg_gc[GTK_WIDGET_STATE(widget)] |
、bg_gc
、dark_gc
和light_gc
索引取值靠一个GtkStateType
类型的参数,该类型可以取如下值:
GTK_STATE_NORMAL, GTK_STATE_ACTIVE, GTK_STATE_PRELIGHT, GTK_STATE_SELECTED, GTK_STATE_INSENSITIVE |
默认的前景色是白色,默认的背景色是暗蓝色。
我们的函数draw_brush()
做实际的屏幕绘制工作。函数如下:
/* 在屏幕上绘制一个矩形 */ static void draw_brush (GtkWidget *widget, gdouble x, gdouble y) { GdkRectangle update_rect; update_rect.x = x - 5; update_rect.y = y - 5; update_rect.width = 10; update_rect.height = 10; gdk_draw_rectangle (pixmap, widget->style->black_gc, TRUE, update_rect.x, update_rect.y, update_rect.width, update_rect.height); gtk_widget_draw (widget, &update_rect); } |
void gtk_widget_draw (GtkWidget *widget, GdkRectangle *area); |
给定的区域需要更新。 X 会最终会产生一个暴露事件(混合区域需要多次调用函数gtk_widget_draw()
),然后会调用暴露事件处理函数,复制相应的部分到屏幕上。
现在我们已经有了一个较完整的绘图程序,只差主窗口部分了。
<<< Previous | Home | Next >>> |
事件处理 | Up | 添加XInput支持 |
相关文章推荐
- 容器构件 Container Widgets 事件盒 The EventBox@GTK+ 2.0 中文教程连载
- 构件概述@GTK+ 2.0 中文教程连载
- 范围构件 Range Widgets示例@GTK+ 2.0 中文教程连载
- 对齐构件 The Alignment widget@GTK+ 2.0 中文教程连载
- 构件的组织@GTK+ 2.0 中文教程连载
- 杂项构件/ 标签 Labels@GTK+ 2.0 中文教程连载
- 无文档构件。。。。。。@GTK+ 2.0 中文教程连载
- 杂项构件/箭头 Arrows@GTK+ 2.0 中文教程连载
- 设置构件的属性@GTK+ 2.0 中文教程连载
- 无窗口构件@GTK+ 2.0 中文教程连载
- 按钮构件 /一般按钮 Normal Buttons@GTK+ 2.0 中文教程连载
- 分栏窗口构件 Paned Window Widgets@GTK+ 2.0 中文教程连载
- 编写你自己的构件 概述@GTK+ 2.0 中文教程连载
- 文本输入构件 Text Entries@GTK+ 2.0 中文教程连载
- 一个构件的剖析@GTK+ 2.0 中文教程连载
- 创建一个复合构件@GTK+ 2.0 中文教程连载
- 组装构件@GTK+ 2.0 中文教程连载
- 从头创建构件@GTK+ 2.0 中文教程连载
- 范围构件 Range Widgets || 滚动条构件 Scrollbar Widgets@GTK+ 2.0 中文教程连载
- 比例构件 Scale Widgets@GTK+ 2.0 中文教程连载