【发布时间】:2017-07-16 18:36:02
【问题描述】:
我想通过继承 DrawingArea 小部件来实现自定义小部件,为此我需要使用 cairo 进行绘制。似乎在 gtk3 中引入了一个名为“draw”的新信号。如何在小部件内绘制?映射和实现信号是否也应该被覆盖?
一个简单的示例代码会很有帮助。谢谢。
【问题讨论】:
我想通过继承 DrawingArea 小部件来实现自定义小部件,为此我需要使用 cairo 进行绘制。似乎在 gtk3 中引入了一个名为“draw”的新信号。如何在小部件内绘制?映射和实现信号是否也应该被覆盖?
一个简单的示例代码会很有帮助。谢谢。
【问题讨论】:
简单地说,您需要覆盖将提供开罗上下文的绘图信号:
gboolean
user_function (GtkWidget *widget,
CairoContext *cr,
gpointer user_data)
然后你可以使用 CairoContext cr来绘制小部件的实际内容。
来自 C API:
GtkDrawingArea 小部件用于创建自定义用户界面 元素。它本质上是一个空白小部件;你可以借鉴它。后 创建绘图区域,应用程序可能要连接到:
鼠标和按钮按下信号以响应用户的输入。 (采用 gtk_widget_add_events() 启用您希望接收的事件。)
当小部件在特定显示器上实例化时,“实现”信号将采取任何必要的操作。 (在中创建 GDK 资源 响应这个信号。)
“size-allocate”信号在小部件改变大小时采取任何必要的行动。
处理重绘小部件内容的“draw”信号。
当小部件发生变化时,小部件应该排队进行一些绘制,例如,在分配大小时,您应该使用gtk_widget_queue_draw 来强制小部件再次绘制它。
示例 - 使用绘图区域不作为子类,但概念仍然存在: (取自Gnome C API)
gboolean
draw_callback (GtkWidget *widget, cairo_t *cr, gpointer data)
{
guint width, height;
GdkRGBA color;
GtkStyleContext *context;
context = gtk_widget_get_style_context (widget);
width = gtk_widget_get_allocated_width (widget);
height = gtk_widget_get_allocated_height (widget);
gtk_render_background (context, cr, 0, 0, width, height);
cairo_arc (cr,
width / 2.0, height / 2.0,
MIN (width, height) / 2.0,
0, 2 * G_PI);
gtk_style_context_get_color (context,
gtk_style_context_get_state (context),
&color);
gdk_cairo_set_source_rgba (cr, &color);
cairo_fill (cr);
return FALSE;
}
[...]
GtkWidget *drawing_area = gtk_drawing_area_new ();
gtk_widget_set_size_request (drawing_area, 100, 100);
g_signal_connect (G_OBJECT (drawing_area), "draw",
G_CALLBACK (draw_callback), NULL);
您还应该阅读 GtkWidget 中有关 Height-for-width 几何管理的信息
我使用 C 是因为在您的问题中没有提及编程语言,同时它是编写所有其他语言的原始 API。
网上有一些关于创建 Gtk+ 自定义 Widgets 的例子。
【讨论】: