使用cairo绘图区域

时间:2016-05-09 13:43:25

标签: gtk cpu-usage cairo

我正在开发一个简单的界面,它模拟使用GTK3和C的LED。当我收到命令时," led"根据命令打开或关闭。我在绘图区域使用Cairo绘制一个代表我的led的圆圈,我使用gtk_widget_queue_draw_area在我的超时功能中更新屏幕。过了一会儿,我的CPU使用率在我的应用程序中增加到100%。

当我收到命令时,我会调用下面的函数

void update_status_led(int led, int status_led)
{

    g_signal_connect(G_OBJECT(darea[led]), "draw", G_CALLBACK(on_draw_event_leds), GINT_TO_POINTER(status_led));

}

所以回调函数" on_draw_event_leds"被称为

gboolean on_draw_event_leds(GtkWidget *widget, cairo_t *cr, 
    gpointer user_data)
{ 
  set_status_led(cr, GPOINTER_TO_INT(user_data));
  return FALSE;
}

因此它调用函数" set_status_led"

void set_status_led(cairo_t *cr, int status)
{
    printf("update status led: %d\n", countref++);
    cairo_reference(cr);
    cairo_set_line_width(cr, 2);  
    cairo_set_source_rgb(cr, 0, 0, 0);
    cairo_arc(cr, 9, 9, 7, 0, 2 * M_PI);
    if (status>0)
    {
      cairo_set_source_rgb(cr, 1, 0, 0); //red
    }
    else
    {
      cairo_set_source_rgb(cr, 0, 0, 0); //black
    }
    cairo_fill(cr);
    cairo_stroke(cr);
    cairo_destroy(cr);
}

我正在使用" printf("更新状态led:%d \ n",countref ++);"知道我的函数被调用多少次,我的日志打印在

下面
New Connection from 127.0.0.1:34589
1 Command Received
update status led: 6
update status led: 7
1 Command Received
update status led: 8
update status led: 9
update status led: 10
1 Command Received
update status led: 11
update status led: 12
update status led: 13
update status led: 14
1 Command Received
update status led: 15
update status led: 16
update status led: 17
update status led: 18
update status led: 19
1 Command Received
update status led: 20
update status led: 21
update status led: 22
update status led: 23
update status led: 24
update status led: 25
1 Command Received
...

可以看出,我只收到一个命令,我的回调函数on_draw_event_leds被多次调用,并且总是增加1个以上的调用 每个收到的命令都没有被删除,而gtk_widget_queue_draw_area再次渲染它们。

有人可以帮助我吗?

谢谢,

1 个答案:

答案 0 :(得分:0)

g_signal_connect()函数只是说"当这个事件发生时,执行此功能"。您可能会将它混淆为gtk_widget_queue_draw(),这是实际导致重新绘制窗口小部件的函数。

有点违反直觉,信号连接很多。这意味着任何数量的函数都可以连接到同一个信号,并且在发出该信号时将调用所有这些函数。因为您反复调用g_signal_connect(),所以您会获得与绘图函数的多个连接,因此将多次调用该绘图函数。

所以你要做的就是将g_signal_connect()转移到你的初始化代码,因为它通常是信号连接的地方,并且有gtk_widget_queue_draw()(或类似的功能) update_status_led()