Реализация перекрывающихся ярлыков - PullRequest
0 голосов
/ 22 апреля 2020

Я пытаюсь реализовать ярлык Ctrl + C, чтобы виджет не мешал другим определенным ярлыкам.

Проблема

Мое окно выглядит так:

  • GtkWindow
    • GtkEntry
    • GtkToggleButton

Часть кода

// --- add checkbox ---
GtkWidget * checkbutton = gtk_check_button_new_with_label("My Checkbox");
gtk_container_add(GTK_CONTAINER(vbox), GTK_WIDGET(checkbutton));

// --- setup checkbox shortcut ---

GtkAccelGroup * accel_group = gtk_accel_group_new();
gtk_window_add_accel_group(GTK_WINDOW(window), accel_group);   

gtk_widget_add_accelerator(checkbutton, "clicked", accel_group, 
                          GDK_KEY_c, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE); 
g_signal_connect(checkbutton, "clicked", G_CALLBACK(onCopyCheckbox), NULL);    
  // problem: this event fires, even if GtkEntry is focussed
  //          it then block the <kbd>Ctrl+C</kbd>-Event of GtkEntry

Ожидаемое поведение

  • Если фокусируется GtkEntry и нажата Ctrl + C, должна быть запущена функция callback1 ().
  • Если сфокусировано GtkToggleButton и нажата Ctrl + C, должно появиться «onCopyCheckbox () с именем \ n».

Фактическое поведение

  • Если сфокусировано GtkEntry и нажата Ctrl + C, выводится «onCopyCheckbox () с именем \ n» и ничего не копируется.
  • Если GtkToggleButton фокусируется и нажимается Ctrl + C, печатается "onCopyCheckbox () с именем \ n".

Пожалуйста, не ...

  • скажите мне, что я должен использовать другой ярлык / ускоритель.

Полный компилируемый и исполняемый код:

#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>

// ------------------------------------------------------------

void
onCopyCheckbox (GtkWidget      *widget,
                GdkDragContext *context,
                gpointer        user_data)
{
  printf("onCopyCheckbox() called\n");
}

// ------------------------------------------------------------

void fillWindow (GtkWindow * window)
{

  // ------- create layout ------------
  GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
  gtk_container_add(GTK_CONTAINER(window),GTK_WIDGET(vbox)); 

  // --- add line edit --- 
  GtkWidget * lineedit = gtk_entry_new();
  gtk_container_add(GTK_CONTAINER(vbox), GTK_WIDGET(lineedit));

  // --- add checkbox ---
  GtkWidget * checkbutton = gtk_check_button_new_with_label("My Checkbox");
  gtk_container_add(GTK_CONTAINER(vbox), GTK_WIDGET(checkbutton));

  // --- setup checkbox shortcut ---

  GtkAccelGroup * accel_group = gtk_accel_group_new();
  gtk_window_add_accel_group(GTK_WINDOW(window), accel_group);   

  gtk_widget_add_accelerator(checkbutton, "clicked", accel_group, 
                            GDK_KEY_c, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE); 
  g_signal_connect(checkbutton, "clicked", G_CALLBACK(onCopyCheckbox), NULL);    
    // problem: this event fires, even if GtkEntry is focussed
    //          it then block the <kbd>Ctrl+C</kbd>-Event of GtkEntry

}

// ------------------------------------------------------------

int main(int argc, char *argv[]) {

  gtk_init(&argc, &argv);

  GtkWindow * window;
  {
    window = (GtkWindow*)gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title (window, "Window title");
    gtk_window_set_default_size (window, 200, 200);
    g_signal_connect(window, "destroy", gtk_main_quit, NULL);
  }

  fillWindow(window);

  gtk_widget_show_all ((GtkWidget*)window);
  gtk_main();

  return 0;
}

// ------------------------------------------------------------

1 Ответ

0 голосов
/ 23 апреля 2020

Представьте, что вы хотите вызвать функцию ниже на Ctrl + C, когда флажок установлен.

void 
shortcutAction(GSimpleAction* a, GVariant * b, gpointer c){
  printf("shortcutAction() called\n");
}

Это способ установки вашего флажка

// --- add checkbox ---
GtkWidget * checkbox = gtk_check_button_new_with_label("My Checkbox");
gtk_container_add(GTK_CONTAINER(vbox), GTK_WIDGET(checkbox));

// ========= setup checkbox shortcut ==============

GtkApplication * app = GTK_APPLICATION(g_application_get_default());

// ------- Part 1: create the action itself -----------
  // All the action you want to add go in one ActionGroup
  GSimpleActionGroup * group = g_simple_action_group_new();

  // define all action you want to have
  //  these action can be basically seen as some kind of signal  
  static const GActionEntry actions[] {
    { .name="print", .activate=shortcutAction}
  };

  // ActionGroup.add(actions[])        
  g_action_map_add_action_entries(G_ACTION_MAP(group), actions, G_N_ELEMENTS(actions), NULL);

  // Widget.addActionGroup(ActionGroup) // connect widget and action group
  //  No you also create a name for the group. Here "checkbox" (but can be anything)
  gtk_widget_insert_action_group (GTK_WIDGET(checkbox), "checkbox", G_ACTION_GROUP(group));

// ------- Part 2: create the shortcut to create the action --------
const gchar * const shortcuts[] = { "<Ctrl>C", NULL };
gtk_application_set_accels_for_action (app, "checkbox.print", shortcuts);

Замечания

Как видно из кода, существует строгое различие между

  • определяющими действиями
  • определяющими ярлыками
...