0

this code show me on xubuntu 21.04 form with size (400px width + 400px height) and with ONE button.

How can I add to this code two buttons?

#include <gtk/gtk.h>

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);
}
Ulrich Eckhardt
  • 16,572
  • 3
  • 28
  • 55
aleks_yolp
  • 17
  • 3
  • You will need something like [GtkBox](https://docs.gtk.org/gtk4/class.Box.html) or [GtkGrid](https://docs.gtk.org/gtk4/class.Grid.html) – Michi Aug 15 '21 at 15:31

1 Answers1

0

In GTK4, I have found that a window (GtkWindow or GtkApplicationWindow) can only have one child. So to include multiple widgets within a window (such as a label and three buttons) one usually has to first create a grid object (GtkGrid), place the widgets within the grid at specified rows and columns, and then set the grid as the child of the window. Using your sample code above, I revised the code to look like the following:

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

This results in establishing a window with the two additional buttons you wanted. I did not know what type of functions those buttons should trigger, so for my revisions to your sample code, I just hooked the two additional buttons to the same closure signal. Following is a sample of the window when I run the program.

enter image description here

I hope that helps you out.

Regards.

Additional Notes:

Regarding the request as how to add "label2" and then have that label's text updated to "Network Connections", the following additions to your sample program could provide a way to do this.

First, a callback function for updating the new label's text would be added to the program (usually at the beginning of the program).

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

Then, within the activation function, the new label would be defined.

GtkWidget *label2   = gtk_label_new("");

Next, the new label widget would be added to the grid (in this example, it was added next to the "label" widget in the first row).

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

Finally, since the request in the comment was to have the label's text updated to "Network Connections", the signal connection for the first button would be revised to call the new "on_button1_clicked" callback function and passing the "label2" widget instead of the "window" widget.

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

The result should net the desired behavior.

enter image description here

Hopefully, that addresses your comment.

Regards.

NoDakker
  • 3,390
  • 1
  • 10
  • 11
  • Another option for layout is [Gtk Box](https://docs.gtk.org/gtk4/class.Box.html). (a combination of what was `hbox` and `vbox` widgets in more programmable versions of Gtk) – David C. Rankin Apr 16 '22 at 04:35
  • I want add "label2" with text: "Network Connections". How to update text of "label2" after "press" to "button1"? – aleks_yolp Apr 17 '22 at 09:14
  • I edited my answer to include additional sample code that provides one method for accomplishing your request. For sure, there are probably other methods for accomplishing this as well. – NoDakker Apr 17 '22 at 17:08