GTK3和cairo太慢了

时间:2018-02-10 20:16:22

标签: c gtk3 cairo

我用GTK3和cairo制作了一个非常简单的动画,这对于这个简单的图形来说太慢了。我不明白为什么这么慢。我尝试使用 gtk_widget_queue_draw_area ,但结果是一样的,没有任何变化。 谁能解释我,为什么它如此缓慢以及我该如何解决?

以下是该计划:

#include <gtk/gtk.h>
#include <cairo.h>

void draw(GtkWidget* widget, cairo_t* cr)
{
    static int width, height,
               posX = 0,
               vX = 1;

    GtkWidget* window = gtk_widget_get_toplevel(widget);
    gtk_window_get_size(GTK_WINDOW(window), &width, &height);

    cairo_set_source_rgb(cr, 0, 0, 0);
    cairo_set_line_width(cr, 1);

    cairo_rectangle(cr, posX, height/2, 1, 1);
    cairo_stroke(cr);

    if(posX + vX >= width || posX + vX == 0)
        vX = -vX;
    posX += vX;

    gtk_widget_queue_draw(window);
}

int main(int argc, char** argv)
{
    GtkWidget* window;
    GtkWidget* darea;

    gtk_init(&argc, &argv);

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    darea = gtk_drawing_area_new();

    gtk_container_add(GTK_CONTAINER(window), darea);

    gtk_window_set_default_size(GTK_WINDOW(window), 500, 400);

    g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
    g_signal_connect(G_OBJECT(darea), "draw", G_CALLBACK(draw), NULL);

    gtk_widget_show_all(window);
    gtk_main();
}

1 个答案:

答案 0 :(得分:1)

您应该使用计时器,例如g_timeout_add。你可以注册g_timeout_add你的新函数redraw每0.05秒调用一次(例如每50毫秒),而redraw不仅要绘制内容而且还要返回TRUE 50毫秒后重新启动。你会发现这样一个50毫秒的延迟可能太小了,你肯定想要增加它。

(请注意,在i5-4690S的Linux / Debian / Sid / x86-64上,您的程序仅占用CPU时间的3%,用time(1)测量...所以它不会太慢;计算机花了97%的时间等待!还记得人眼在大多数情况下看不到比30到60赫兹更快的速度。

程序中没有动画代码(因为任何动画都应定期运行)。仅在需要时才会调用event loop(在gtk_main中)。您可能只想部分重新绘制窗口。

你的做法是错误的。您不希望使用gtk_widget_queue_draw重复绘图,您希望它定期再次发生(例如,从gtk_widget_queue_draw注册的新redraw例程中调用g_timeout_add )。你将通过实验调整那段时间。

你也可以使用gtk_widget_add_tick_callback(由c-smile评论)。我认为你不需要它(因为我猜你的动画可能会运行得太快)。

研究某些GTK examples的源代码(特别是clock示例)。另请参阅thisthat。查看custom drawing示例,并查看aclock的来源。

(你的程序不是太慢,但你的draw可能不够频繁地调用;没有代码可以重复它;你应该use the gdb debugger并用{{编译你的代码1}}传递给-Wall -g - 除gcc提供的其他标志外)