Программно добавлять обработчики сигналов в виджеты по идентификатору, определенному в glade xml - PullRequest
1 голос
/ 07 июля 2019

Я пытаюсь создать графический интерфейс, используя gtk3.0 в c, используя gnome-builder 3.22.

Я создал графический интерфейс с помощью встроенного дизайнера в gome-builder, который является просто glade, и для каждого виджета я назначил идентификатор. Я только определил идентификаторы, так как встроенная версия glade внутри gnome-builder не завершена и не имеет вкладки для сигналов / обработчиков, это есть только в автономной версии Glade.

Я хочу знать, есть ли способ программно добавить функции обработчика сигналов / функции обратного вызова к идентификаторам, указанным в xml, без необходимости делать это в самом xml или использовать автономное программное обеспечение Glade.

Это довольно маленький графический интерфейс, поэтому несколько лишних строк кода меня не беспокоят.

Я также попытался добавить обработчики / обратные вызовы в xml и использовать функцию автоматического подключения gtkbuilder для автоматического подключения этих обработчиков / сигналов, но это тоже не сработало.

Важные файлы в проекте были загружены в gist:

  • main.c
  • ба-компрессионного window.ui
  • ба-компрессионного window.c

адрес: https://gist.github.com/Jebiel/08fdf3b8fbbd34e09bd48d05d79d9cbf

короткий URL: http://gg.gg/eh4hn

1 Ответ

0 голосов
/ 08 июля 2019

Да, вы можете сделать это. Вы можете использовать g_signal_connect или g_signal_connect_object для подключения обработчика к объекту. В первом случае вам потребуется вручную отключить обработчик, когда вам больше не нужен запуск обработчика (т. Е. Когда объект завершен), а в последнем случае это будет сделано для вас, когда объект уничтожен (т. Е. Завершен).

Вы можете подключить обработчик сигнала любым методом после того, как объект будет готов к использованию. Ниже я переопределяю метод constructed, который будет запущен после создания объекта (здесь, BaCompressionWindow).

Минимальный пример будет выглядеть так (back_button должен быть определен в .ui файле):

static void
back_button_clicked_cb (GtkButton           *button,
                        BaCompressionWindow *self)
{
  g_assert (GTK_IS_BUTTON (button));
  g_assert (BA_IS_COMPRESSION_WINDOW (self));

  g_warning ("Back button clicked");
}

static void
ba_compression_window_constructed (GObject *object)
{
  BaCompressionWindow *self = (BaCompressionWindow *)self;

  G_OBJECT_CLASS (ba_compression_window_parent_class)->constructed (object);

  g_signal_connect (self->back_button, "clicked",
                   G_CALLBACK (back_button_clicked_cb),
                   self);
}

static void
ba_compression_window_class_init (BaCompressionWindowClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);

  object_class->constructed = ba_compression_window_constructed;
}

Более простой способ сделать то же самое - добавить обработчик сигнала в файл GtkBuilder .ui, например так:

<object class="GtkButton" id="back_button">
  <property name="visible">1</property>
  <property name="label">Back</property>
  <signal name="clicked" handler="back_button_clicked_cb"
          object="BaCompressionWindow"/>
</object>

и связать обратный вызов в файле c (см. Остальной код выше)

static void
ba_compression_window_class_init (BaCompressionWindowClass *klass)
{
  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);

  /* Other code */

  gtk_widget_class_bind_template_callback (widget_class, back_button_clicked_cb);
}

Кстати, пожалуйста, добавьте соответствующий код здесь вместо ссылки на исходный файл

...