For testing purposes, I wrote a small program calling a GtkAlertDialog and showing the results of the user selection.
I noticed the topic of GCancellable.
Despite studying the documentation, I did not succeed in finding a meaningful use for it. Here is the corresponding programme section:
#include"g-cancellable.h"
void presst(GObject* quelle, GAsyncResult* res, gpointer user_data)
{
GtkAlertDialog *dialog = GTK_ALERT_DIALOG(quelle);
GError *err = NULL;
int button = gtk_alert_dialog_choose_finish (dialog, res, &err);
if (err)
{
g_print("An error occured!\n");
g_print("Error Message: %s\n", err->message);
g_free(err);
return;
}
if (button == 1)
g_print("Cancel\n");
if (button == 0)
g_print("O.k.\n");
g_object_unref(dialog); // GtkAlertDialog dispose.
}
void clicked (GtkWidget *button, gpointer user_data)
{
GtkWidget* box =gtk_widget_get_parent(button);
GtkWidget* window = gtk_widget_get_parent(box);
GCancellable *cancel = G_CANCELLABLE(user_data);
GtkAlertDialog* alert_dialog = gtk_alert_dialog_new (
"DANGER!\nA mistake\n");
const char* buttons[] = {"O.k.","Cancel",NULL};
gtk_alert_dialog_set_buttons(alert_dialog,buttons);
// Esc - Button
gtk_alert_dialog_set_cancel_button (alert_dialog,1);
// Enter - Button
gtk_alert_dialog_set_default_button(alert_dialog,0);
// Dialog
gtk_alert_dialog_choose (alert_dialog,
GTK_WINDOW(window),
G_CANCELLABLE(cancel), // Which function ??
(GAsyncReadyCallback)presst,
NULL);
}
void activate (GtkApplication *app, gpointer data)
{
GtkWidget *window;
window =gtk_application_window_new(app);
gtk_widget_set_size_request(window,50,50);
GCancellable* cancel = g_cancellable_new ();
GtkWidget *button = gtk_button_new_with_label("Click me");
g_signal_connect(button,"clicked",G_CALLBACK(clicked),cancel);
GtkWidget *box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL,10);
gtk_box_append(GTK_BOX(box),button);
gtk_window_set_child(GTK_WINDOW(window),box);
gtk_widget_set_visible(window,TRUE);
}
Can anyone help me here?
GCancellable is an object that is intended to stop a process. 4 steps in principle are necessary for this:
Step 1 Create GCancellable-Object:
GCancellable* cancel = g_cancellable_new ();
Step 2 Connect the GCancellable-Object to a process:
// Dialog
gtk_alert_dialog_choose (alert_dialog,
GTK_WINDOW(window),
G_CANCELLABLE(cancel), // connecting to gcancellable
(GAsyncReadyCallback)user_action, // for user reaction
cancel);
}
Step 3 Connect the signal emitting from GCancellable
g_cancellable_connect(cancel,
G_CALLBACK(gecancelld), // unused
GINT_TO_POINTER(timer),
(GDestroyNotify) timer_destroy_func); // destroy timer
// if GCancellable is
// unref
Step 4 set GCancellable to cancelled, to cancel the process.
g_cancellable_cancel(cancel);
g_object_unref(cancel); // GCancellable dispose
In connection with GtkAlertDialog, this can now be used as follows:
#include"g-cancellable.h"
// if timeout
gboolean time_out(gpointer user_data)
{
GCancellable *cancel = G_CANCELLABLE(user_data);
g_cancellable_cancel(cancel);
g_object_unref(cancel);
return TRUE;
}
// for user interaction
void user_action(GObject* quelle, GAsyncResult* res, gpointer user_data)
{
GtkAlertDialog *dialog = GTK_ALERT_DIALOG(quelle);
GError *err = NULL;
int button = gtk_alert_dialog_choose_finish (dialog, res, &err);
if (err)
{
g_print("An error occured!\n");
g_print("Error Message: %s\n", err->message);
g_free(err);
g_object_unref(dialog);
return;
}
if (button == 1)
g_print("Cancel\n");
if (button == 0)
g_print("O.k.\n");
GCancellable *cancel = G_CANCELLABLE(user_data);
g_cancellable_cancel(cancel);
g_object_unref(cancel); // GCancellable dispose
g_object_unref(dialog); // GtkAlertDialog dispose.
}
void timer_destroy_func(gpointer data)
{
guint timer = GPOINTER_TO_INT(data);
g_source_remove(timer);
}
void gecancelld()
{
// unused
};
void dialog_called (GtkWidget *button, gpointer user_data)
{
GtkWidget* box =gtk_widget_get_parent(button);
GtkWidget* window = gtk_widget_get_parent(box);
// create Object GCancellable
GCancellable* cancel = g_cancellable_new ();
guint timer = g_timeout_add(10000, G_SOURCE_FUNC(time_out), (gpointer)cancel);
g_cancellable_connect(cancel,
G_CALLBACK(gecancelld), // unused
GINT_TO_POINTER(timer),
(GDestroyNotify) timer_destroy_func); // destroy timer
// if GCancellable is
// unref
GtkAlertDialog* alert_dialog = gtk_alert_dialog_new (
"DANGER!\nA mistake\n");
const char* buttons[] = {"O.k.","Cancel",NULL};
gtk_alert_dialog_set_buttons(alert_dialog,buttons);
// Esc - Button
gtk_alert_dialog_set_cancel_button (alert_dialog,1);
// Enter - Button
gtk_alert_dialog_set_default_button(alert_dialog,0);
// Dialog
gtk_alert_dialog_choose (alert_dialog,
GTK_WINDOW(window),
G_CANCELLABLE(cancel), // connecting to gcancellable
(GAsyncReadyCallback)user_action, // for user reaction
cancel);
}
void activate (GtkApplication *app, gpointer data)
{
GtkWidget *window;
window =gtk_application_window_new(app);
gtk_widget_set_size_request(window,50,50);
GtkWidget *button = gtk_button_new_with_label("Click me");
g_signal_connect(button,"clicked",G_CALLBACK(dialog_called),NULL);
GtkWidget *box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL,10);
gtk_box_append(GTK_BOX(box),button);
gtk_window_set_child(GTK_WINDOW(window),box);
gtk_widget_set_visible(window,TRUE);
}
The program section shows a GtkAlertDialog, which, if the user does not react, is closed again after a timeout. At the same time, an error message is issued, which can then be used in the program.
Enjoy testing and programming.