main.cpp
#include <gtk/gtk.h>
void onDestroy(GtkWidget* widget, gpointer data) {
gtk_main_quit();
}
gboolean onDeleteEvent(GtkWidget* widget, GdkEvent* event, gpointer data) {
GtkWidget *dialog;
dialog = gtk_message_dialog_new(GTK_WINDOW(widget), GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
"Czy na pewno chcesz opuścić program?");
gtk_window_set_title(GTK_WINDOW(dialog), "Pytanie");
GtkResponseType result = (GtkResponseType)gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
if (result == GTK_RESPONSE_YES) {
return FALSE;
}
return TRUE;
}
int main(int argc, char** argv) {
GtkBuilder *builder;
GError *error;
GtkWidget *window;
gtk_init(&argc, &argv);
builder = gtk_builder_new();
error = NULL;
gtk_builder_add_from_file(builder, "main_window.ui", &error);
if (error) {
g_print("Wystąpił błąd: %s\n", error->message);
g_error_free(error);
return -1;
}
window = GTK_WIDGET(gtk_builder_get_object(builder, "wndHelloWorld"));
g_signal_connect(G_OBJECT(window), "delete-event", G_CALLBACK(onDeleteEvent), NULL);
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(onDestroy), NULL);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
Program ten demonstruje jak opuścić działającą aplikację po kliknięciu w przycisk TAK w okienku dialogowym wymagającym potwierdzenia operacji zamknięcia programu. Aby to osiągnąć podpięliśmy funkcje obsługi zdarzenia "delete-event" - onDeleteEvent oraz sygnału "destroy" - onDestroy. Funkcje te różnią się nieco nagłówkami. Pierwsza z nich ma nagłówek:
gboolean user_function(GtkWidget *widget, GdkEvent *event, gpointer user_data)
natomiast druga:
void user_function(GtkWidget *object, gpointer user_data)
O tym jak wygląda nagłówek funkcji obsługi zdarzenia możemy się przekonać w programie devhelp, wpisując w nim frazy wyszukiwania delete-event oraz destroy signal.
Dlaczego użyliśmy tych zdarzeń? Ponieważ w funkcji onDeleteEvent możemy się wycofać z chęci zamknięcia aplikacji zwracając wartość TRUE. Jeśli natomiast zwrócimy w niej wartość FALSE, to okno główne zostanie zniszczone a przed jego zniszczeniem wyemitowany zostanie sygnał destroy. Funkcja onDestroy odpowiada za opuszczenie funkcji gtk_main() po to, aby program zakończył działanie po zniszczeniu okna głównego aplikacji. Natomiast funkcja onDeleteEvent wyświetla okno dialogowe z zapytaniem "Czy na pewno chcesz opuścić program?". Jeśli użytkownik kliknie przycisk TAK - aplikacja zostanie zamknięta. W przeciwnym razie będzie kontynuowała działanie.
Okienko dialogowe tworzymy przy pomocy funkcji gtk_message_dialog_new i przypisujemy do zmiennej dialog. Funkcja ta przyjmuje następujące parametry:
Następnie utworzonemu widgetowi okna dialogowego nadajemy tytuł przy pomocy funkcji gtk_window_set_title. Teraz jesteśmy gotowi na wyświetlenie okna dialogowego. Robimy to wywołując funkcję gtk_dialog_run i przekazując jej nasz widget. Funkcja ta przetwarza w pętli komunikaty okna dialogowego aż do naciśnięcia któregokolwiek z przycisków. Wtedy kończy działanie i zwraca w postaci liczby całkowitej gint typ przycisku, który został kliknięty. Rezultat rzutujemy do typu GtkResponseType i zapamiętujemy w zmiennej result. Teraz możemy już zniszczyć okno dialogowe przy pomocy funkcji gtk_widget_destroy. Następnie testujemy zawartość zmiennej result i jeśli jest równa GTK_RESPONSE_YES, to zwracamy wartość FALSE pozwalając zamknąć okno główne. W przeciwnym razie przerywamy operację zamknięcia zwracając TRUE.