如何在Gtk 2窗口上创建cairo_t

4du*_*ies 3 c gtk gtk2 cairo

我有一个旧应用程序,现在正在编译Gtk 2,但我需要介绍使用Cairo.我无法弄清楚如何从我的Widgets创建必要的cairo上下文(cairo_t).

这是我到目前为止要学习的代码,从Gtk 3教程修改(*ahem*cribbed).问题的关键是从窗口小部件创建一个cairo表面.就目前而言,该调用是一个草图,它不会编译,更不用说运行了.记住,我的目标是Gtk2,而不是3,至少在这一点上.

/* Snitched from http://zetcode.com/gfx/cairo/cairobackends/ on 13 Jan 2014 */
#include <cairo.h>
#include <cairo-xlib.h>
#include <gtk/gtk.h>

int main(int argc, char *argv[])
{
  GtkWidget *window;
  GtkWidget *darea;
  cairo_surface_t *surface;
  cairo_t *cr;

  gtk_init(&argc, &argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

  darea = gtk_drawing_area_new();
  gtk_container_add(GTK_CONTAINER(window), darea);

  g_signal_connect(window,          "destroy", G_CALLBACK(gtk_main_quit), NULL);

  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
  gtk_window_set_default_size(GTK_WINDOW(window), 400, 90);
  gtk_window_set_title(GTK_WINDOW(window), "GTK window");

  surface = cairo_xlib_surface_create(
      gtk_widget_get_display(window),   /* must be Display *, not struct GdkDisplay * */
      window,                           /* must be Drawable (no star) */
      gtk_widget_get_visual(window),    /* must be Visual * */
      gtk_widget_get_width(window),     /* int */
      gtk_widget_get_height(window)     /* int */
      );
  cr = cairo_create(surface);
  cairo_set_source_rgb(cr, 0, 0, 0);
  cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL, 
     CAIRO_FONT_WEIGHT_NORMAL);
  cairo_set_font_size(cr, 40.0);

  cairo_move_to(cr, 10.0, 50.0);
  cairo_show_text(cr, "Discipline is power.");

  gtk_widget_show_all(window);

  gtk_main();

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

Jus*_*nen 6

我希望教程没有在main()中进行cairo绘图...绘制到GTK小部件的有意义的地方是在expose事件中(如果你想强制从其他地方重绘,只需调用gtk_widget_queue_draw()).无论如何,获得cairo上下文的简单方法是gdk_cairo_create().

像这样的东西:

static gboolean
on_expose_event (GtkWidget *widget,
                 GdkEventExpose *event,
                 gpointer data)
{
    cairo_t *cr;

    cr = gdk_cairo_create (gtk_widget_get_window (widget));
    cairo_move_to (cr, 30, 30);
    cairo_show_text (cr, "Text");

    cairo_destroy (cr);

    return FALSE;
}

g_signal_connect(darea, "expose-event",
                 G_CALLBACK(on_expose_event), NULL);
Run Code Online (Sandbox Code Playgroud)

Jan Bodnar有一个更完整的例子(最后).

在我看来,这在GTK3中要好得多.尽管如此,即使您的目标是移植到GTK3,也可以将绘图更改为首先使用cairo - 之后更改为GTK3应该只是简化代码.