我正在开发一个简单的界面,它模拟使用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再次渲染它们。
有人可以帮助我吗?
谢谢,
答案 0 :(得分:0)
g_signal_connect()
函数只是说"当这个事件发生时,执行此功能"。您可能会将它混淆为gtk_widget_queue_draw()
,这是实际导致重新绘制窗口小部件的函数。
有点违反直觉,信号连接很多。这意味着任何数量的函数都可以连接到同一个信号,并且在发出该信号时将调用所有这些函数。因为您反复调用g_signal_connect()
,所以您会获得与绘图函数的多个连接,因此将多次调用该绘图函数。
所以你要做的就是将g_signal_connect()
转移到你的初始化代码,因为它通常是信号连接的地方,并且有gtk_widget_queue_draw()
(或类似的功能) update_status_led()
。