2

Althought Gtk.table is deprecated, I am getting better results with it, instead of the recommended Gtk.Grid.

It is probably my mistake, but I couldn't find the problem.

My aim is to create a Gtk window with a notebook at the top and two buttons below. These buttons should be horizontally aligned.

My code with table, works as expected:

uses Gtk

class TestWindow : Window
    init
        // General characteristics of the window
        title = "Gtk Containers"
        default_height = 250
        default_width = 250
        window_position = WindowPosition.CENTER
        destroy.connect(Gtk.main_quit)

        // Now building the notebook
        var notebook = new Gtk.Notebook()
        var label1 = new Gtk.Label("Page one")
        var label2 = new Gtk.Label("Page two")
        var child1 = new Gtk.Label("Go to page 2 for the answer")
        var child2 = new Gtk.Label("Go to page 1 for the answer")
        notebook.append_page(child1, label1)
        notebook.append_page(child2, label2)

        // Now building the table
        var table = new Table(2,2,true)
        var button1 = new Gtk.Button.with_mnemonic("Button_1")
        var button2 = new Button.with_mnemonic("Button_2")

        // Attaching all elements into the table
        table.attach_defaults(notebook, 0,2,0,1)
        table.attach_defaults(button1, 0,1,1,2)
        table.attach_defaults(button2, 1,2,1,2)
        add(table)

init
    Gtk.init (ref args)
    var test = new TestWindow ()
    test.show_all ()
    Gtk.main ()

However, the same code with the recommended Gtk.Grid gives me the two buttons without the notebook:

uses Gtk

class TestWindow : Window
    init
        // General characteristics of the window
        title = "Gtk Containers"
        default_height = 250
        default_width = 250
        window_position = WindowPosition.CENTER
        destroy.connect(Gtk.main_quit)

        // Now building the notebook
        var notebook = new Gtk.Notebook()
        var label1 = new Gtk.Label("Page one")
        var label2 = new Gtk.Label("Page two")
        var child1 = new Gtk.Label("Go to page 2 for the answer")
        var child2 = new Gtk.Label("Go to page 1 for the answer")
        notebook.append_page(child1, label1)
        notebook.append_page(child2, label2)

        // Now building the grid
        var grid = new Grid()
        var button1 = new Gtk.Button.with_mnemonic("Button_1")
        var button2 = new Button.with_mnemonic("Button_2")

        // Attaching all elements into the grid
        grid.attach(notebook, 0,2,0,1)
        grid.attach(button1, 0,1,1,2)
        grid.attach(button2, 1,2,1,2)

init
    Gtk.init (ref args)
    var test = new TestWindow ()
    test.show_all ()
    Gtk.main ()

How to achieve the aim using Grid instead of Tables? Not asking for code, just a pointer.

lf_araujo
  • 1,991
  • 2
  • 16
  • 39

3 Answers3

4

gtk_table_attach_defaults() and gtk_grid_attach() operate differently. The official documentation in C points this out.

Given

        thing.attach(widget, a,b,c,d)

For GtkTable, the four numbers a, b, c, and d are the actual column and row numbers that the given edge of the widget should occupy. a is the left edge, b is the right edge, c is the top edge, and d is the bottom edge.

For GtkGrid, a is the column and b is the row that the top-left corner of the widget should occupy, c is the number of columns wide the widget is, and d is the number of rows tall the widget is.

Or in other words,

        table.attach_defaults(widget, left, right, top, bottom)

is the same as

        grid.attach(widget, left, top,
            right - left + 1, bottom - top + 1)

Hopefully some part of that explanation clears things up.

The quick fix for your code would be

        grid.attach(notebook, 0,0,2,1)
        grid.attach(button1, 0,1,1,1)
        grid.attach(button2, 1,1,1,1)
andlabs
  • 11,290
  • 1
  • 31
  • 52
3

For Gtk.Grid:

attach(child, left, top, width, height)

Parameters:

  • child (Gtk.Widget) – the widget to add
  • left (int) – the column number to attach the left side of child to
  • top (int) – the row number to attach the top side of child to
  • width (int) – the number of columns that child will span
  • height (int) – the number of rows that child will span

For Gtk.Table:

attach(child, left_attach, right_attach, top_attach, bottom_attach, xoptions, yoptions, xpadding, ypadding)

Parameters:

  • child (Gtk.Widget) – The widget to add.
  • left_attach (int) – the column number to attach the left side of a child widget to.
  • right_attach (int) – the column number to attach the right side of a child widget to.
  • top_attach (int) – the row number to attach the top of a child widget to.
  • bottom_attach (int) – the row number to attach the bottom of a child widget to.
  • xoptions (Gtk.AttachOptions) – Used to specify the properties of the child widget when the table is resized.
  • yoptions (Gtk.AttachOptions) – The same as xoptions, except this field determines behaviour of vertical resizing.
  • xpadding (int) – An integer value specifying the padding on the left and right of the widget being added to the table.
  • ypadding (int) – The amount of padding above and below the child widget.

Note: That the columns and rows are indexed from zero.

0

andlabs's explanation is correct, although his conversion adding 1 to grid.attach right and bottom values didn't work well to me. As I had to convert many of these values, I've prepared a python script to ease this process, HTH:

import sys

if len(sys.argv) < 2: raise Exception('Argument not provided')

args = ''.join([str(x) for x in sys.argv[1:]]).split(',')

if len(args) != 4: raise Exception('Please provide 4 attach arguments')

left, right, top, bottom = map(lambda a: int(a), args)
print("{}, {}, {}, {}".format(left, top, right - left, bottom - top))
Community
  • 1
  • 1
AndreLDM
  • 2,117
  • 1
  • 18
  • 27