我有一个简单的应用程序,它应该使用GTK+和Cairo将装饰过的轮子每x毫秒旋转这么多度。我在下面有一些代码,可以从计时器调用cairo_rotate()。但是,图像不会改变。是否必须使图像无效才能触发expose-event?我对Cairo非常陌生,如果有一个简单的例子演示如何在GTK+中使用Cairo旋转图像,我将不胜感激。
#include <cairo.h>
#include <gtk/gtk.h>
cairo_surface_t *image;
cairo_t *cr;
gboolean rotate_cb( void )
{
    cairo_rotate (cr, 1);
    //cairo_paint(cr);
    printf("rotating\n");
    return( TRUE );
}
static gboolean
on_expose_event(GtkWidget *widget,
    GdkEventExpose *event,
    gpointer data)
{
  cr = gdk_cairo_create (widget->window);
  cairo_set_source_surface(cr, image, 0, 0);
  cairo_paint(cr);
  printf("Paint\n");
  //cairo_destroy(cr);
  return FALSE;
}
int main(int argc, char *argv[])
{
  GtkWidget *window;
  image = cairo_image_surface_create_from_png("wheel.png");
  gtk_init(&argc, &argv);
  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  g_signal_connect(window, "expose-event",
      G_CALLBACK (on_expose_event), NULL);
  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), 500, 500); 
  gtk_widget_set_app_paintable(window, TRUE);
  gtk_widget_show_all(window);
  g_timeout_add(500, (GSourceFunc) rotate_cb, NULL);
  gtk_main();
  cairo_destroy(cr);
  cairo_surface_destroy(image);
  return 0;
}发布于 2012-06-12 08:18:13
您需要将旋转存储在一个变量中,并在绘制之前将cairo_rotate(cr,rotation_amt);调用到on_expose_event方法中。
如果图像居中,还可以平移到窗口的中心,旋转并平移回来,以使轮子围绕其中心旋转。
cairo_translate(cr, width / 2.0, height / 2.0);
cairo_rotate(cr, rotation_amt);
cairo_translate(cr, - image_w / 2.0, - image_h / 2.0);
cairo_set_source_surface(cr, image, 0, 0);
cairo_paint(cr);我希望这是对的。
正如ptomato所说,您需要通过从rotate_cb调用gtk_widget_queue_draw来使您的绘图图面无效。而且为Cairo上下文保留一个全局变量是多余的。图像不会旋转,因为新创建的上下文加载了一个单位矩阵,并且您之前的所有变换都被重置。
https://stackoverflow.com/questions/10986142
复制相似问题