0

I am trying to reset a label of a button to its initial (default) value of None, which does not work as expected. Here's the minimal example:

from gi import require_version
require_version('Gtk', '3.0')
from gi.repository import Gtk


class GUI(Gtk.Window):

    def __init__(self):
        super().__init__()
        self.connect('destroy', Gtk.main_quit)
        self.set_position(Gtk.WindowPosition.CENTER)

        self.grid = Gtk.Grid(hexpand=True, vexpand=True)
        self.add(self.grid)
        button = Gtk.Button(hexpand=True, vexpand=True)
        self.grid.attach(button, 0, 0, 1, 1)
        button.connect('clicked', self.on_button_clicked)

    def on_button_clicked(self, button: Gtk.Button) -> None:
        print(label := button.get_label(), type(label))
        button.set_label(label)


def main() -> None:

    win = GUI()
    win.show_all()
    Gtk.main()


if __name__ == '__main__':
    main()

Result:

$ python example.py 
None <class 'NoneType'>
Traceback (most recent call last):
  File "/home/neumann/example.py", line 21, in on_button_clicked
    button.set_label(label)
TypeError: Argument 1 does not allow None as a value

What's the correct way to do this?

Note: Before somebody suggests it: I do not want to set the label to an empty string, since that will change the size of the button, which is noticeable on a larger grid of buttons:

from gi import require_version
require_version('Gtk', '3.0')
from gi.repository import Gtk


class GUI(Gtk.Window):

    def __init__(self):
        super().__init__()
        self.connect('destroy', Gtk.main_quit)
        self.set_position(Gtk.WindowPosition.CENTER)

        self.grid = Gtk.Grid(hexpand=True, vexpand=True)
        self.add(self.grid)
        
        for x in range(3):
            button = Gtk.Button(hexpand=True, vexpand=True)
            button.connect('clicked', self.on_button_clicked)
            self.grid.attach(button, x, 0, 1, 1)

    def on_button_clicked(self, button: Gtk.Button) -> None:
        print(label := button.get_label(), type(label))
        button.set_label('')


def main() -> None:

    win = GUI()
    win.show_all()
    Gtk.main()


if __name__ == '__main__':
    main()

1 Answer 1

1

I'm not sure what your use case is, but you can try adding a GtkLabel child and set the string there:

from gi import require_version
require_version('Gtk', '3.0')
from gi.repository import Gtk


class GUI(Gtk.Window):

    def __init__(self):
        super().__init__()
        self.connect('destroy', Gtk.main_quit)
        self.set_position(Gtk.WindowPosition.CENTER)

        self.grid = Gtk.Grid(hexpand=True, vexpand=True)
        self.add(self.grid)

        for x in range(3):
            button = Gtk.Button(hexpand=True, vexpand=True)
            label = Gtk.Label()
            button.add(label)
            button.connect('clicked', self.on_button_clicked)
            self.grid.attach(button, x, 0, 1, 1)

    def on_button_clicked(self, button: Gtk.Button) -> None:
        label = button.get_child()
        print(text := label.get_label(), type(text))
        label.set_label('')
        # or hide it if you want
        # label.hide()


def main() -> None:

    win = GUI()
    win.show_all()
    Gtk.main()


if __name__ == '__main__':
    main()

GtkButton may be creating the internal GtkLabel child only when a label is set (which should be a valid string). And since the hexpand and vexpand for the GtkButton are set to True, they may be getting propagated to the internal GtkLabel.

If you simply want all the buttons to have same width and height, you may only need grid.set_row_homogeneous() and grid.set_column_homogeneous()

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

Comments

Your Answer

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