Retrasos de g_signal (C, GTK+)

I've got a little GTK-Application with two buttons (A, B) and a drawing area (C). When I click on A, C's size should be recalculated and set with gtk_widget_set_size_request(). This will cause an exposición-evento, whose handler will calculate some data. Further, the click on A emitirá un clickeado señal en B, whose handler needs the data calculated by C's exposición-evento.

In fact everything works fine, but the exposición-evento delays somehow, and the clickeado handler is called before and the data (you may guess it) is missing.

a_handler() {
   new_size = calculate_size();
   gtk_widget_set_size_request(C, new_size); //Will cause expose-event
   g_signal_emit_by_name(B, "clicked");
}

b_handler() {
   calculate_something(data); //Error
}

c_handler() {
   draw_something();
   data = calcluate_data();
}

¿Qué puedo hacer?

preguntado el 28 de agosto de 12 a las 12:08

2 Respuestas

Gtk (and most other GUI toolkits) does the painting and event handling all in one thread. Therefore when the expose event is emitted, it goes into a queue and will be handled only after a_handler devoluciones.

The best approach in my opinion would be to move the calculation somewhere else, if there is not some good reason to tie it into GUI drawing. For example, there could be a separate method calculate_data that is called both from b_handler y c_handler.

The next best way is to call gdk_window_process_updates to force the expose event to be handled immediately: http://developer.gnome.org/gdk/stable/gdk-Windows.html#gdk-window-process-updates

Respondido 28 ago 12, 14:08

But there is a good reason to tie it into GUI drawing, that's the problem. This "calculation" is very computationally intensive and to be more precise it's somewhat like that: c_handler() { for() { data = calcluate_data(); draw_something(data); } } (I'm afraid I don't get this correct, damn!) - Génesis Rock

The ugly fix is typically to add calls to gtk_main_iteration(), for instance between the call to gtk_widget_set_size_request() and the signal-emission.

Respondido 28 ago 12, 13:08

Hey dude, that's perfekt! Just use while (gtk_events_pending()) gtk_main_iteration(); - Génesis Rock

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.