1

I'm trying to write a simple GUI using Gtk4 (in Python), but I'm having trouble with getting rid of padding (and I don't understand why the padding is there).

The goal is pretty simple - I need a Gtk.Grid showing a bunch of images with some basic metadata. AFAICS a good way to do that is Window -> ScrollWindow -> Grid -> Box -> (Image + Label). And in general this works, except that the images have a lot of top/bottom padding, so the labels have a lot of empty space around, which I don't like but can't get rid of it :-(

See this screenshot

Here's a simple example demonstrating this:

import gi
import sys

gi.require_version('Gtk', '4.0')

from gi.repository import Gtk, GdkPixbuf


def create_image(file_name, img_width, cssProvider = None):

    info = 'file:' + file_name

    box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)

    # box.get_style_context().add_provider(cssProvider, Gtk.STYLE_PROVIDER_PRIORITY_USER)
    # box.add_css_class('thumbnail')

    box.set_hexpand(True)

    # add image to top
    pixbuf = GdkPixbuf.Pixbuf.new_from_file(file_name)

    # calculate height to keep width and aspect ratio
    img_height = pixbuf.get_height() * img_width / pixbuf.get_width()

    image = Gtk.Image.new_from_pixbuf(pixbuf)
    image.set_size_request(img_height, img_width)

    # image.get_style_context().add_provider(cssProvider, Gtk.STYLE_PROVIDER_PRIORITY_USER)
    # image.add_css_class('thumbnail-image')

    box.append(image)

    # add label to bottom
    label = Gtk.Label(label=info)

    # label.get_style_context().add_provider(cssProvider, Gtk.STYLE_PROVIDER_PRIORITY_USER)
    # label.add_css_class('thumbnail-label')

    box.append(label)

    return box


class MainWindow(Gtk.ApplicationWindow):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.cssProvider = None
#       self.cssProvider = Gtk.CssProvider()
#       self.cssProvider.load_from_data(b"""
#.thumbnail {background-color: white; color: black; border: 1px solid #ddd; margin: 5px; padding: 0; }
#.thumbnail-label { font-size: 12pt; margin: 0; padding: 0; }
#.thumbnail-image { margin: 0; padding: 0; }
#.green { background-color: #bfb; }""")

        self.set_default_size(900, 600)
        self.set_title("MyApp")

        self.grid = Gtk.Grid()

        self.window = Gtk.ScrolledWindow()
        self.window.set_child(self.grid)

        self.set_child(self.window)

        idx = 0
        prev = None

        for idx in range(0,20):
            # 4 columns
            i = int(idx / 4)
            j = int(idx % 4)

            image = create_image('frog.jpg', 1920/4 - 10, self.cssProvider)

            self.grid.attach(image, j, i, 1, 1)


class MyApp(Gtk.Application):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.connect('activate', self.on_activate)
    
    def on_activate(self, app):
        self.win = MainWindow(application=app)
        self.win.present()

app = MyApp(application_id="com.example.GtkApplication")
app.run(sys.argv)

This needs an image called 'frog.jpg', e.g. this one.

The sizes are meant to work on 1920x1080, with 4 columns. I'm sure it could be done more dynamic (i.e. to work better with resized windows etc.), but I believe that's a separate issue.

I've tried a bunch of things, including styling using CSS, etc. (which is commented-out in the sample).

I also experimented with setting hexpand/vexpand on different widgets, not adding the label, and various similar things.

1
  • I've tried to build the interface in a visual tool (instead of building it by hand).In Glade it works pretty much exactly the way I wanted (images are maximal size), but Glade supports only GTK3 and I planned to use GTK4. For GTK4 the only tool I found is Cambalache (flathub.org/apps/details/ar.xjuan.Cambalache) and that seems to always produce a layout with the empty space. So perhaps this is something that changed between GTK3 and GTK4? However, Cambalache seems to be somewhat new/quirky and harder to use than Glade, so maybe it just sets some properties differently. Commented Dec 2, 2022 at 16:50

1 Answer 1

1

Apparently using Gtk.Picture instead of Gtk.Image solves the issue - with Picture there's no unwanted empty space/padding. Seems a bit confusing, considering Picture/Image are often used as synonyms. Maybe it's in the gtk docs somewhere, but I don't see it - certainly not without reading between the lines. I see some discussion of "natural size" but I don't see how'd that imply this behavior. Anyway, if others face the same issue, try using Gtk.Picture.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for this "self answer" I was trying to solve a similar problem and using Gtk.Picture worked for me! I'm making a grid of thumbnail that when clicked will play a video so my design is a bit similar but I'm using ScrolledWindow -> flowbox. You might want to look at flowbox I think its better suited to automatically adjust to different screen sizes

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.