You never show the children of Test. You never show Test either, to be fair.
Widgets, in GTK3, are hidden by default; you need to explicitly show them by calling show(), or recursively show them by calling show_all() on one of their ancestor.
Try replacing:
window.show()
with:
window.show_all()
and you should see the child widgets appear. Except for the button you add in a timeout: for that you will need to call show() explicitly, as it’s added after the show_all() call returns.
When I wrote “you never show the children of Test” I literally meant: you need to call show() on every child you add, otherwise it won’t be visible.
ETA: Your timeout_add() function is also wrong, the interval is the first argument, not the last.
Once you explicitly show the widgets, everything works as it should:
import gi
gi.require_version("Gtk", "3.0")
gi.require_version("GLib", "2.0")
from gi.repository import Gtk, GLib
class Test(Gtk.Bin):
def __init__(self):
super().__init__()
# Add a box, and show it
box = Gtk.Box()
self.add(box)
box.show()
def on_timeout():
# Add a button, and show it
button = Gtk.Button.new_with_label("you will not see me")
box.add(button)
button.show()
return GLib.SOURCE_REMOVE
GLib.timeout_add(100, on_timeout)
window = Gtk.Window(title="Hello World")
window.connect("destroy", Gtk.main_quit)
# Add the Test widget, and show it
test = Test()
window.add(test)
test.show()
# Just show the window
window.show()
Gtk.main()
You can call show_all() as many times as you want, but you typically want to control which widgets you wish to show, not perform a blanket “please show every single widget in this branch of the widget tree”. For instance, you could have multiple widgets added to a container, and then show/hide them depending on some state; if you call show_all() every time you add a widget, you’ll end up showing everything that’s currently hidden on purpose.
You’re making it much more complicated than it necessarily is.
You don’t need to constantly set a widget visible: once a widget is marked as visible with show(), it stays visible until you call hide().
Call show() every time you add a widget to a parent container—or, if you’re using a UI description XML file and GtkBuilder, add a <property name="visible>True</property> element.
Is there some sort of language barrier, here? Should I explain again what I wrote?
You can call show() on every widget you add; you can also call show_all() on their ancestor. The important thing is that you must make a widget visible after adding it to a parent.