Ниже приведена только кнопка, которая при нажатии может выдавать выходные данные на консоли. (Выход только значение локального счетчика цикла и глобальной переменной.)Какое периодическое событие и источник (X-сервер сгенерирован?) - это приложение GTK, захватывающее каждую секунду или около того?
EDIT: Дело в том, что код, чтобы исследовать, как работает gtk_main_interation(); поэтому я не хочу обертывать этот вызов вокруг цикла gtk_events_pending(). Код носит чисто педагогический характер.
Странная часть кода является то, что вместо этого «щелкнул» обработчик события есть цикл, который вызывает gtk_main_iteration(). gtk_main_iteration предполагается блокировать, если нет ожидающих события событий. Однако игра с этим маленьким приложением показывает, что основной цикл GTK захватывает какое-то событие каждую секунду или около того, даже если ничего не происходит. Чтобы увидеть это, попробуйте просто щелкнуть и отпустить кнопку, а затем отпустить мышь (не перемещая курсор вообще).
Предположительно это событие генерируется сервером X (или основным контуром GTK) в качестве своего рода вещи синхронизации. Я не знаю, как это событие вызвано, и поисковые запросы Google меня терпят.
#include <gtk/gtk.h>
#include <glib.h>
#include <gmp.h>
#include <unistd.h>
#define UNUSED(x) (void)(x)
typedef struct _Data {
GtkWidget *window1,
*button1;
} Data;
int g=0;
void on_button1_clicked(GtkWidget *widget, Data *data) {
int l=0;
UNUSED(widget);
UNUSED(data);
for(l=0;l<10;++l) {
gtk_main_iteration();
printf("l=%d g=%d|",l,g++);
fflush(stdout);
}
printf("\n\n");
}
int main (int argc, char *argv[]) {
Data *data;
gtk_init(&argc, &argv);
data=g_slice_new0(Data);
/* add widgets and objects to our structure */
data->window1=gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size(GTK_WINDOW(data->window1),250,250);
data->button1=gtk_button_new_with_label("Start");
gtk_container_add(GTK_CONTAINER(data->window1),GTK_WIDGET(data->button1));
gtk_signal_connect(GTK_OBJECT(data->window1), "delete-event",
gtk_main_quit, NULL);
gtk_signal_connect(GTK_OBJECT(data->button1), "clicked",
G_CALLBACK(on_button1_clicked), NULL);
gtk_widget_show_all(GTK_WIDGET(data->window1));
gtk_main();
/* Don't forget to free the memory! */
g_slice_free(Data, data);
return 0;
}
Я компиляции с
gcc -Wall -Wextra -Wconversion -pedantic `pkg-config --cflags --libs gtk+-2.0` events.c -o events
Два комментария к коду: а) вам не следует выделять данные с помощью g_slice_new, если у вас нет большого количества значений sizeof (Data), потому что в этом случае вы используете больше памяти, чем необходимо. Кроме того, вам не нужно освобождать данные до того, как программа закроется, ОС сделает это за вас. – iain