How to understand Gtk+ properties and make GtkGrid expand to available area?
Asked Answered
T

2

6

I'm stumbling through Gtk+ tutorials and the reference, trying to understand how to get a decent layout done. The docs say you should use GtkGrid instead of the deprecated Box/HBox/VBox, but I’m having trouble getting the GtkGrid to expand to the full window size. Using gtk_widget_set_hexpand has no effect on the GtkGrid at all.

This answer suggests "looking at the expand property" but I can't find information about what this properties actually are and how you set them (I just assumed there always is a getter/setter pair for each property, but in this case there is no gtk_widget_set_expand function).

What am I missing?


Update:

Setting the expand property still won't work - the buttons "stick" in the top left corner of the window. Here's the code:

static void initializeGui() {
    GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "Blabla");
    gtk_window_set_default_size(GTK_WINDOW(window), 800, 500);
    gtk_window_set_hide_titlebar_when_maximized(GTK_WINDOW(window), TRUE);
    gtk_container_set_border_width(GTK_CONTAINER(window), 10);
    g_signal_connect(window, "delete-event", G_CALLBACK(onWindowDelete), NULL);
    g_signal_connect(window, "destroy", G_CALLBACK(onWindowDestroy), NULL);

    GtkWidget *mainbox = gtk_grid_new();
    g_object_set(G_OBJECT(mainbox), "expand", TRUE, NULL);
        GtkWidget *button = gtk_button_new_with_label("Short button");
        g_signal_connect(button, "clicked", G_CALLBACK(onButtonClick), NULL);
        gtk_grid_attach(GTK_GRID(mainbox), button, 0, 0, 1, 1);

        button = gtk_button_new_with_label("Very very long button");
        gtk_grid_attach(GTK_GRID(mainbox), button, 1, 0, 1, 1);

        button = gtk_button_new_with_label("Tiny btn");
        gtk_widget_set_halign(button, GTK_ALIGN_END);
        gtk_grid_attach(GTK_GRID(mainbox), button, 1, 1, 1, 1);
    gtk_container_add(GTK_CONTAINER(window), mainbox);   
    gtk_widget_show_all(window);
}
Timmons answered 29/8, 2013 at 14:37 Comment(0)
P
6

It is very hard to say what you are missing since you did not include example code. In addition to hexpand and vexpand, knowing the halign and valign properties could be helpful -- although what you described should be doable with just the expands.

You should also be aware of the older way of dealing with this, container "child properties" (see e.g. gtk_box_pack_start() to see how they were/are used). This can get confusing as there is a expand child property and the hexpand/vexpand widget properties... Both are clearly documented though.

The docs say you should use GtkGrid instead of the deprecated Box/HBox/VBox

This is not the whole story with regards to GtkBox: it is not deprecated and can be used when you need a column or row container. That said, a single row/column GtkGrid does the exact same thing and has, in my opinion, a cleaner api...

I can't find information about what this properties actually are and how you set them

The documentation typically explains what the properties are: https://developer.gnome.org/gtk3/stable/GtkWidget.html#GtkWidget--expand. If there is no setter (or you want to set multiple properties at once) you can use g_object_set:

g_object_set (widget, "expand", TRUE, NULL);

Update:

From the added code it seems like GtkGrid is actually expanded as you want (but that is impossible to visually confirm). The buttons on the other hand are not set to expand. If you do that, I believe you can even remove the GtkGrids expand because the property should "propagate up" the container chain).

You haven't mentioned what you wanted the buttons to do, but you may want to then use halign/valign for different alignments (fill/center/etc).

Update 2:

Based on the description of what you really wanted to achieve, the below changes seem to do what you ask for. The button on the left is set to expand and align to left, the other buttons align to right: as a result all buttons hug the sides of the window and have the minimum width.

#include <gtk/gtk.h>

int main( int argc, char *argv[])
{
    gtk_init(&argc, &argv);

    GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_default_size(GTK_WINDOW(window), 800, 500);

    GtkWidget *mainbox = gtk_grid_new();

    GtkWidget *button = gtk_button_new_with_label("Short button");
    gtk_widget_set_hexpand (button, TRUE);
    gtk_widget_set_halign (button, GTK_ALIGN_START);
    gtk_grid_attach(GTK_GRID(mainbox), button, 0, 0, 1, 1);

    button = gtk_button_new_with_label("Very very long button");
    gtk_widget_set_halign(button, GTK_ALIGN_END);
    gtk_grid_attach(GTK_GRID(mainbox), button, 1, 0, 1, 1);

    button = gtk_button_new_with_label("Tiny btn");
    gtk_widget_set_halign(button, GTK_ALIGN_END);
    gtk_grid_attach(GTK_GRID(mainbox), button, 1, 1, 1, 1);

    gtk_container_add(GTK_CONTAINER(window), mainbox);
    gtk_widget_show_all(window);

    gtk_main();

    return 0;
}
Pickaninny answered 29/8, 2013 at 20:3 Comment(5)
Well GtkBox is not deprecated yet but docs state you shouldn't use it for "future-proof" code. Didn't realize that properties are a part of GObject and not Gtk - shame on me :) For some reason it still doesn't work with the expand property set. I added the code maybe you could take a look at it?Timmons
You have a point with the future proofing. I've updated the answer, hope you get the hang of it -- GTK box model is a bit quirky (and the legacy cruft doesn't help) but it is quite powerful when you 'get it'.Pickaninny
Yes, if you expand the button, the change will propagate up to the container. However I would be interested in a solution where the buttons in column 0 touch the left window side, the button in column 1 the right window side, and all the buttons only occupy the needed space and nothing more. As you can see I already tried the button's halign property in my code, unfortunately not achieving the desired effect.Timmons
So I tried your code and as far as I can see hexpand + halign seem to do exactly what you describe (see updated answer)... Let me know if there's still something I'm missing.Pickaninny
I believe the position on GtkBox was reversed and it is now considered totally OK in GTK 3/4 and presumably future.Reproachless
M
-1

follow code is Vala code to show grid and expand property:

            m_form_detail_grid = new Gtk.Grid();
            m_form_detail_grid.row_spacing = 10;
            m_form_detail_grid.column_spacing = 5;
            // m_form_detail_grid.column_homogeneous = true;
            m_form_detail_grid.expand = true;
            m_form_detail_grid.margin = 30;
            m_form_detail_grid.orientation = Gtk.Orientation.VERTICAL;


            for (int index = 0; index < column_count; index++) {
                column_title = this.m_data_model.get_column_title(index).replace ("_", "__"); 
                column_label = new Gtk.Label(column_title);
                column_label.hexpand = false;
                column_label.halign = Gtk.Align.END;

                column_widget = new Gtk.Entry();
                column_widget.editable = true;
                column_widget.hexpand = true;
                column_widget.halign = Gtk.Align.FILL;

                m_form_detail_grid.attach (column_label, 0, index, 1, 1);
                m_form_detail_grid.attach (column_widget, 1, index, 7, 1);
            }
Malita answered 10/5, 2019 at 13:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.