2013-03-27 3 views
-2

Ниже приведена только кнопка, которая при нажатии может выдавать выходные данные на консоли. (Выход только значение локального счетчика цикла и глобальной переменной.)Какое периодическое событие и источник (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 
+0

Два комментария к коду: а) вам не следует выделять данные с помощью g_slice_new, если у вас нет большого количества значений sizeof (Data), потому что в этом случае вы используете больше памяти, чем необходимо. Кроме того, вам не нужно освобождать данные до того, как программа закроется, ОС сделает это за вас. – iain

ответ

0

этот код может быть педагогическим, но это совершенно нарушена, и даже отдаленно не идиоматическое:

GtkButton::Clicked сигнал не испускается системой оконного : он полностью синтезирован самим GtkButton; это зависит от приема button-release-event после button-press-event, пока указатель все еще находится в пределах GtkButton, который возник из печати; X11 не имеет понятия «щелкнуть» (внутри или без этой семантики).

Этот пример практически не показывает поток событий, который вы можете или не можете получить под X11. если вы хотите увидеть поток событий, вы можете скомпилировать GTK + с включенными сообщениями об отладке (./configure --enable-debug=yes) и установить переменную окружения GDK_DEBUG перед запуском приложения. GTK + распечатает информацию о каждом полученном X событии, включая тип события.

+0

Как это «полностью сломано», если оно делает то, что я хочу? (плюс, код, который компилируется, не «полностью нарушен», и его вывод должен быть понятным). Я не уверен, что вы подразумеваете под «идиоматическим» здесь. Кроме того, Xlib знает о событиях нажатия кнопки. Полагаю, я могу попытаться включить отладку (я не использую configure, хотя), и я могу попробовать это. Мой вопрос довольно прямолинейный: «Что порождает эти события?» Он будет иметь совершенно правильный ответ одной фразы, и я не понимаю, как вы можете сказать: «этот пример практически ничего не показывает о потоке событий». Оно делает. –