将 GCancellable 与 GtkAlertDialog 一起使用

问题描述 投票:0回答:1

出于测试目的,我编写了一个小程序,调用 GtkAlertDialog 并显示用户选择的结果。

我注意到了 GCancellable 的主题。

尽管研究了文档,但我没有成功找到它的有意义的用途。 这是相应的程序部分:

#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);
}

有人可以帮我吗?

c memory-management gtk4
1个回答
0
投票

GCancellable 是一个旨在停止进程的对象。 为此原则上需要 4 个步骤:

第 1 步创建 GCancellable 对象:

GCancellable*  cancel = g_cancellable_new ();

第 2 步将 GCancellable-Object 连接到进程:

 // Dialog 
  gtk_alert_dialog_choose (alert_dialog,
                   GTK_WINDOW(window),  
                   G_CANCELLABLE(cancel),  // connecting to gcancellable
                  (GAsyncReadyCallback)user_action, // for user reaction 
                   cancel);
}

步骤 3 连接 GCancellable 发出的信号

g_cancellable_connect(cancel,
                        G_CALLBACK(gecancelld), // unused 
                        GINT_TO_POINTER(timer),
                        (GDestroyNotify) timer_destroy_func); // destroy timer
                                                       // if GCancellable is
                                                       // unref 

Schritt 4 将 GCancellable 设置为已取消,以取消该进程。

    g_cancellable_cancel(cancel);
    g_object_unref(cancel);  // GCancellable dispose  

与 GtkAlertDialog 结合使用,现在可以按如下方式使用:

#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);
}

程序部分显示了一个GtkAlertDialog,如果用户没有反应,它会在超时后再次关闭。同时发出错误消息,然后可以在程序中使用。

享受测试和编程。

© www.soinside.com 2019 - 2024. All rights reserved.