Как добавить две кнопки в эту форму GTK4?

      
static void activate(GtkApplication *app, void *user_data) {
    GtkWidget *window = gtk_application_window_new(app);


    gtk_window_set_child(GTK_WINDOW(window), gtk_label_new("Hello World!"));
    gtk_window_present(GTK_WINDOW(window));




  gtk_window_set_default_size (GTK_WINDOW (window), 400, 400);


    // Create a new button
    GtkWidget *button = gtk_button_new_with_label ("press 123");
    gtk_window_set_child (GTK_WINDOW (window), button);
    // When the button is clicked, close the window passed as an argument
 g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_window_close), window);
}

int main(int argc, char *argv[]) {
    g_autoptr(GtkApplication) app = gtk_application_new(NULL, G_APPLICATION_FLAGS_NONE);
    g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);
 
    return g_application_run(G_APPLICATION(app), argc, argv);
}

этот код показывает мне форму xubuntu 21.04 с размером (ширина 400 пикселей + высота 400 пикселей) и с ОДНОЙ кнопкой .. Как я могу добавить к этому коду две кнопки? Я скомпилировал этот код на xubuntu 21.04 с помощью следующей команды в эмуляторе терминала:

      g++ -o gtk4-my gtk4-my.c $(pkg-config --cflags --libs gtk4)

и начиная со следующей команды в эмуляторе терминала:

      user@user-PC:~$ ./gtk4-my

1 ответ

В GTK4 я обнаружил, что у окна (GtkWindow или GtkApplicationWindow) может быть только один дочерний элемент. Таким образом, чтобы включить несколько виджетов в окно (например, метку и три кнопки), обычно нужно сначала создать объект сетки (GtkGrid), разместить виджеты в сетке в указанных строках и столбцах, а затем установить сетку как дочернюю. окна. Используя приведенный выше пример кода, я изменил код, чтобы он выглядел следующим образом:

      #include <gtk/gtk.h>

static void activate(GtkApplication *app, void *user_data)
{
  GtkWidget *window = gtk_application_window_new(app);
  GtkWidget *grid   = gtk_grid_new();
  GtkWidget *label  = gtk_label_new("Hello World");

  //gtk_window_set_child(GTK_WINDOW(window), gtk_label_new("Hello World!"));

  gtk_window_set_default_size (GTK_WINDOW (window), 400, 400);

  gtk_grid_set_column_spacing(GTK_GRID(grid),10);
  gtk_grid_set_row_spacing(GTK_GRID(grid), 6);
  // Create a new button
  GtkWidget *button1 = gtk_button_new_with_label ("Press 1");
  GtkWidget *button2 = gtk_button_new_with_label ("Press 2");
  GtkWidget *button3 = gtk_button_new_with_label ("Press 3");

  gtk_grid_attach(GTK_GRID(grid), label, 0, 0, 3, 1);
  gtk_grid_attach(GTK_GRID(grid), button1, 0, 1, 1, 1);
  gtk_grid_attach(GTK_GRID(grid), button2, 1, 1, 1, 1);
  gtk_grid_attach(GTK_GRID(grid), button3, 2, 1, 1, 1);

  gtk_window_set_child (GTK_WINDOW (window), grid);
  // When the button is clicked, close the window passed as an argument
  g_signal_connect_swapped (button1, "clicked", G_CALLBACK (gtk_window_close), 
  window);
  g_signal_connect_swapped (button2, "clicked", G_CALLBACK (gtk_window_close), 
  window);
  g_signal_connect_swapped (button3, "clicked", G_CALLBACK (gtk_window_close),
  window);

  gtk_window_present(GTK_WINDOW(window));
}

int main(int argc, char *argv[])
{
  g_autoptr(GtkApplication) app = gtk_application_new(NULL, 
  G_APPLICATION_FLAGS_NONE);
  g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);

  return g_application_run(G_APPLICATION(app), argc, argv);
}

Это приводит к созданию окна с двумя дополнительными кнопками, которые вы хотели. Я не знал, какие функции должны запускать эти кнопки, поэтому для моих изменений в вашем примере кода я просто подключил две дополнительные кнопки к одному и тому же сигналу закрытия. Ниже приведен пример окна, когда я запускаю программу.

Я надеюсь, что это поможет вам.

С Уважением.

Дополнительные примечания:

Что касается запроса о том, как добавить «метку2», а затем обновить текст этой метки на «Сетевые подключения», следующие дополнения к вашему примеру программы могут предоставить способ сделать это.

Во-первых, в программу будет добавлена ​​функция обратного вызова для обновления текста новой метки (обычно в начале программы).

      void on_button1_clicked (GtkLabel *lbl)
{
    gtk_label_set_text(lbl, "Network Connections");
}

Затем в функции активации будет определена новая метка.

      GtkWidget *label2   = gtk_label_new("");

Затем в сетку будет добавлен новый виджет метки (в этом примере он был добавлен рядом с виджетом «метка» в первой строке).

      gtk_grid_attach(GTK_GRID(grid), label2, 1, 0, 2, 1);

Наконец, поскольку запрос в комментарии должен был обновить текст метки на «Сетевые подключения», сигнальное соединение для первой кнопки будет изменено, чтобы вызвать новую функцию обратного вызова «on_button1_clicked» и передать виджет «label2» вместо виджет «окно».

      g_signal_connect_swapped (button1, "clicked", G_CALLBACK (on_button1_clicked), label2);

Результат должен соответствовать желаемому поведению.

Надеюсь, это относится к вашему комментарию.

С Уважением.

Другие вопросы по тегам