I just learned GTK3 yesterday because of a project I'm currently doing for school, I have a bit of knowledge in C but none in GTK.
I wanted to know if there was a way for me to remove all children on existing grid, and subsequently repopulate by creating new buttons to the same grid.
I currently am only able to delete the button that was clicked on, but not all the buttons with the code:
g_signal_connect(button, "clicked", G_CALLBACK(gtk_widget_destroy), button)
I have also tried deleting the grid itself using:
g_signal_connect(button, "clicked", G_CALLBACK(gtk_widget_destroy), grid)
and
g_signal_connect_swapped(button, "clicked", G_CALLBACK(NewCallback), grid)
and trying to create a new grid using my self defined function NewCallback()
to no avail.
From what I understand from the documentation, the order is roughly 1 Container > 1 Window > 1 Grid > Multiple Widgets. Please correct me if I'm wrong.
#include <gtk/gtk.h>
static void NewCallback(GtkWidget *grid, gpointer user_data)
{
gtk_widget_destroy(grid);
GtkWidget *gridNew;
GtkWidget *window;
gridNew = gtk_grid_new();
window = gtk_widget_get_toplevel(grid);
gtk_window_set_title(GTK_WINDOW(window), "NewWindow");
}
static void activate(GtkApplication *app, gpointer user_data)
{
GtkWidget *window;
GtkWidget *grid;
GtkWidget *button;
/* create a new window, and set its title */
window = gtk_application_window_new(app);
gtk_window_set_title(GTK_WINDOW(window), "Test Program");
gtk_container_set_border_width(GTK_CONTAINER(window), 100);
/* Here we construct the container that is going pack our buttons */
grid = gtk_grid_new();
/* Pack the container in the window */
gtk_container_add(GTK_CONTAINER(window), grid);
button = gtk_button_new_with_label("Test 1");
g_signal_connect(button, "clicked", G_CALLBACK(printFunc), "1");
g_signal_connect_swapped(grid, "clicked", G_CALLBACK(gtk_widget_destroy), button);
/* Place the first button in the grid cell (0, 0), and make it fill Span 2 columns */
gtk_grid_attach(GTK_GRID(grid), button, 0, 0, 2, 1);
button = gtk_button_new_with_label("Test 2");
g_signal_connect(button, "clicked", G_CALLBACK(printFunc), "2");
/* Place the button in the grid cell (0, 1), and make it fill Span 2 columns */
gtk_grid_attach(GTK_GRID(grid), button, 0, 1, 2, 1);
g_signal_connect_swapped(grid, "clicked", G_CALLBACK(gtk_widget_destroy), button);
}
CodePudding user response:
The "clicked"
signal callback has a GtkButton
as the first argument (which is the button that got clicked) and a user_data
pointer (which is given as the last argument in g_signal_connect(button, "clicked", G_CALLBACK(gtk_widget_destroy), grid)
(which is grid
)), and the function gtk_widget_destroy()
takes in one argument-the widget to destroy. Here, it's always the button
.
What you can do is to use g_signal_connect_swapped()
. which will reverse the first and last arguments of the callback (ie, user_data
will be passed as the first argument, and thus gtk_widget_destroy()
will be fed with the user_data
as the argument.
So you could simply write g_signal_connect_swapped(button, "clicked", G_CALLBACK(gtk_widget_destroy), grid)
which will destroy the grid
when the button
is clicked, though you likely want an additional function as GCallback
which will destroy the grid and repopulate it:
static void
ai_button_clicked_cb (GtkButton *button,
gpointer user_data)
{
GtkGrid *grid = user_data;
g_assert (GTK_IS_GRID (grid));
/* Remove all widgets in column 0 */
gtk_grid_remove_column (grid, 0);
/* Now add more buttons to the grid */
}
static void
activate (GtkApplication *app,
gpointer user_data)
{
// ...
g_signal_connect (button, "clicked", G_CALLBACK (ai_button_clicked_cb), grid);
// ...
}
You may find that this is against the C standard (passing 1 arguments to a function that accepts only 1), but this has been heavily used in GObject
.