我试图让随机位置的图像旋转。我正在看另一个类似的帖子(rotate image)。但我无法让事情发挥作用。
#include <gtk/gtk.h>
#include <cairo.h>
GtkWidget *window;
static void rotate_cb()
{
gtk_widget_queue_draw(window);
}
static gboolean on_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
{
GtkWidget *img = (GtkWidget *)(data);
gint w = gtk_widget_get_allocated_width (img);
gint h = gtk_widget_get_allocated_height (img);
gtk_widget_realize(img);
cairo_surface_t *surface = gdk_window_create_similar_surface(gtk_widget_get_window (img), CAIRO_CONTENT_COLOR, w, h);
cairo_t *cr = cairo_create (surface);
cairo_translate(cr, w/2, h/2);
cairo_rotate(cr, 2);
cairo_set_source_surface(cr, surface, -w/2, -h/2);
cairo_paint(cr);
cairo_destroy(cr);
cairo_surface_destroy(surface);
return FALSE;
}
int main(int argc, char *argv[])
{
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size(GTK_WINDOW(window), 600, 600);
gtk_widget_set_app_paintable(window, TRUE);
GtkWidget *l = gtk_layout_new(NULL, NULL);
gtk_container_add(GTK_CONTAINER(window), l);
GtkWidget *img = gtk_image_new_from_file("example.png");
gtk_layout_put(GTK_LAYOUT(l), img, 300, 300);
g_signal_connect(window, "draw", G_CALLBACK (on_expose_event), img);
g_signal_connect(window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
GtkWidget *button = gtk_button_new_with_label("button");
g_signal_connect(button, "clicked", G_CALLBACK(rotate_cb), NULL);
gtk_layout_put(GTK_LAYOUT(l), button, 0, 0);
gtk_widget_show_all(window);
gtk_main();
}
窗口确实收到了绘制信号,但我不知道如何连接gtkwidget和cairo_surface_t。
或许有更好的方法可以做到这一点(没有开罗)。我更喜欢各种各样的想法!谢谢!
答案 0 :(得分:0)
GtkWidget draw
信号处理程序原型应为:
gboolean user_function (GtkWidget *widget, CairoContext *cr, gpointer user_data)
中所述
当小部件应该呈现自身时,会发出此信号。该 小部件的左上角必须绘制在传递的原点 在上下文中,并根据返回的值调整大小 gtk_widget_get_allocated_width()和 gtk_widget_get_allocated_height()。
连接到此信号的信号处理程序可以修改cairo上下文 以任何他们喜欢的方式作为cr传递,并且不需要恢复它。该 信号发射负责在和之前调用cairo_save() 调用处理程序后的cairo_restore()。
信号处理程序将获得一个已经设置为剪辑区域的cr 小部件的脏区域,即需要重新绘制的区域。 复杂的小部件,希望避免完全重绘自己 可以获得剪辑区域的完整范围 gdk_cairo_get_clip_rectangle(),或者他们可以获得更细粒度 肮脏地区的代表 cairo_copy_clip_rectangle_list()。参数
widget - 接收信号的对象
cr - 绘制到
的cairo上下文user_data - 连接信号处理程序时设置的用户数据。
因此,您的on_expose_event
函数原型必须更改,并且将为您提供cairo上下文:
static gboolean on_expose_event(GtkWidget *widget, cairo_t *cr, gpointer data)
{
.... // your code must change too
}