pythongtkpygobject

Is it possible to remove button borders on Gtk4 Button in Python?


Is it possible to remove or change button borders for Gtk4 buttons?

The buttons have borders as shown here:

Button border example

My intention is to create a list of Buttons in a vertical box that are clickable for their clicked signal. Based on the doc for a Button I don't see a way to actually remove the borders.

This is the current structure of the Button.

class MyButton(Gtk.Button):
    def __init__(self):
        super().__init__()
        label = Gtk.Label()
        label.set_label("Hello")
        self.set_hexpand(True)
        self.set_child(label)

I have tried using the set_property method from Gobject.Object that Button inherited from. Using the method with margin worked fine (As in no excpetions being raised), but using border or border-with would raise a TypeError telling that the object doesn't have the property border or border-width.

...
self.set_property("border-width", 0)
# TypeError: object of type `__main__+MyButton' does not have property `border-width'

I have found solutions on SO, but they are extremely outdated and for much older versions of Gtk, so they didn't provide any help on the subject.

Is Gtk just not suitable for this? Is there any other alternative approaches?


Solution

  • To set border width/style you shall have to modify widget CSS. But since you only have to remove the button border, you can apply the predefined flat CSS style class with button.add_css_class("flat").

    You can find CSS class names in libadwaita docs at https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/style-classes.html which overlaps a lot with GTK style classes.

    A minimal python example:

    #!/usr/bin/env python3
    
    # button.py
    #
    # Run: python3 ./button.py
    #
    # Author: Mohammed Sadiq <www.sadiqpk.org>
    #
    # SPDX-License-Identifier: LGPL-2.1-or-later OR CC0-1.0
    
    import sys
    
    import gi
    
    gi.require_version("Gtk", "4.0")
    from gi.repository import GLib, Gtk
    
    
    class MyApplication(Gtk.Application):
        def __init__(self):
            super().__init__(application_id="org.example.SomeButton")
            GLib.set_application_name("Example Button")
    
        def do_activate(self):
            label = Gtk.Label(label="Hello")
            button = Gtk.Button(label="Button 1")
            button.add_css_class("flat")
            box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=12)
            box.set_margin_start(12)
            box.set_margin_end(12)
            box.append(label)
            box.append(button)
    
            window = Gtk.ApplicationWindow(
                application=self, default_width=300, default_height=400
            )
            window.set_child(box)
            window.present()
    
    
    app = MyApplication()
    exit_status = app.run(sys.argv)
    sys.exit(exit_status)