#c #c #events #gtk
#c #c #Мероприятия #gtk
Вопрос:
Я пытаюсь зафиксировать событие в окне GTK при перемещении окна. Я делаю это с помощью чего-то, что выглядит следующим образом:
void mycallback(GtkWindow* parentWindow, GdkEvent* event, gpointer data)
{
// do something...
}
...
GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_add_events(GTK_WIDGET(window), GDK_CONFIGURE);
g_signal_connect_(G_OBJECT(window), "configure-event", G_CALLBACK(mycallback), NULL);
...
Это работает — событие правильно вызывается при перемещении окна… но это также вызывается при изменении размера окна. Это имеет побочный эффект, заключающийся в том, что подэлементы окна не изменяются, как это было бы, если бы я не подключал событие.
Согласно этой таблице в документах GTK, событие GDK_CONFIGURE не распространяется. Если событие не распространяется, как я могу по-прежнему определять движение окна, позволяя ему изменять размер должным образом?
примечание: я использую GTK версии 2.12.9
Ответ №1:
Люк, как вы обнаружили, возврат FALSE позволяет событию распространяться. Это объясняется в руководстве по gtk здесь
Ответ №2:
Neuro- Я не верил, что это сработает, потому что сигнатура функции возвращала void, а не gboolean. Для усмешек я изменил:
void mycallback(GtkWindow* parentWindow, GdkEvent* event, gpointer data)
Для
gboolean mycallback(GtkWindow* parentWindow, GdkEvent* event, gpointer data)
Я бы подумал, что это приведет к несоответствию типов типам обратного вызова, но это не так. Возврат TRUE, как вы предложили, не работает … но, как ни странно, возвращает FALSE. В этом случае кажется, что событие может распространяться.
Редактировать:
В соответствии с руководством по GTK (спасибо Мэтту):
Значение, возвращаемое этой функцией, указывает, следует ли распространять событие дальше с помощью механизма обработки событий GTK. Возвращаемое значение TRUE указывает, что событие было обработано и что оно не должно распространяться дальше. Возврат FALSE продолжает обычную обработку событий.
Комментарии:
1. Это не вызовет несоответствия типов из-за приведения к
G_CALLBACK
, но должно быть возвращаемое значение, поскольку я думаю, что здесь лучше вызватьvoid
функцию и не указывать ожидаемое возвращаемое значение, что означает, что поддельное логическое значение будет считано из какой-то несвязанной части стека и т.д.
Ответ №3:
вы не получите ошибку несоответствия типов для обработчиков сигналов, потому что в gtk вы приводите их все к одному типу, используя G_CALLBACK, независимо от их фактической подписи. Подпись объявляется динамически во время выполнения в функции class_init объекта GObject, поэтому нет способа ввести check их статически. Вы ДОЛЖНЫ ознакомиться с документацией по интересующему вас сигналу и убедиться, что сигнатура обработчиков совпадает с сигнатурой сигнала.
Комментарии:
1. И интересно, и раздражает. Я уверен, что у них есть причина для такого нарушения безопасности типов, но я не могу сказать, что для меня это звучит как хорошая идея.
2. Это должен был быть комментарий к ответу Люка, а не сообщение. @luke Конечно, причина, по которой они используют стирание типов, заключается в том, что в противном случае им пришлось бы объявлять и реализовывать произвольное количество перегрузок, структур хранения и т.д. Для каждого возможного указателя на функцию. В лучшем случае непрактично.
Ответ №4:
Ну, я в основном использую gtkmm (C оболочку GTK). Но, если я правильно помню, если вы хотите распространить сигнал на родительский сервер, ваш обработчик должен вернуть FALSE (gint), что означает «Я НЕ обрабатывал это событие». Поэтому я думаю, что если вы вернете (gint)FALSE в mycallback, это должно сработать.