Программно добавить обработчики сигналов к виджетам по идентификатору, определенному в поляне xml

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

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

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

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

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

Важные файлы проекта загружены в суть:

  • main.c
  • ba-сжатие-window.ui
  • ba-сжатие-window.c

основной адрес: https://gist.github.com/Jebiel/08fdf3b8fbbd34e09bd48d05d79d9cbf

короткая ссылка: http://gg.gg/eh4hn


person Jebiel    schedule 07.07.2019    source источник


Ответы (1)


Да, вы можете это сделать. Вы можете использовать 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);
}

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

person Mohammed Sadiq    schedule 08.07.2019