'PyGObject "realize" callback won't fire on loading sub windows

I have an app with GUI based on PyGObject Gtk. I need to load/display different forms, and the forms are constructed from string created using Glade. The pseudo code is as follow:

class MyGui:

  # Input:
  #   guistrs: list of glade GUI strings [form1, form2, ...].
  def __init__(self, guistrs):
      self.window = Gtk.Window()
      self.forms = guistrs
      self.loadaform(self.forms[0])

  def loadaform(self, guistr):
      # guistr should have a GtkBox 'boxMain' which contains 
      # a GtkDrawingArea 'drawMain' and other elements.
      self.builder = Gtk.Builder.new_from_string(guistr, -1)

      # Unload the current form (boxMain holding elements) if any.
      if self.boxMain is not None:
          self.window.remove(self.boxMain)
          self.boxMain = None

      # Get handle to the new form.
      self.boxMain = self.builder.get_object("boxMain")
      # Get handle to the main label.
      self.drawMain = self.builder.get_object("drawMain")
      # Set callback that should be called when the element is rendered.
      self.drawMain.connect("realize", self.on_realize)

      self.window.add(self.boxMain)
      self.window.fullscreen()
      self.window.show_all()  # this should trigger self.on_realize().

  def on_realize(self, widget):
      window = widget.get_window()
      self.xid = window.get_xid()
      print(f'Get xid for "{self.name}": {self.xid}')
      return

Everything works fine the first time the app allocates a MyGui object and starts the GUI thread Gtk.main(). However, subsequent calls to loadaform(guistr) will load and display the new form, but won't trigger the on_realize callback. Just wonder what I am missing here? TIA.



Solution 1:[1]

The realize signal is emitted only once, when the toolkit is creating windowing system resources; those resources continue to exist until unrealize is emitted.

You code, though, is incorrect: a GtkLabel has no windowing system resources associated to it, so it won't have an XID. The XID of the window will be the XID of the top level to which the label belongs; and since you're not changing the top level, the XID will stay the same.

On top of that, the XID will only ever make sense if your application is running under X11; other windowing systems have no idea what an XID even is. You should not use XID, or rely on X11 to begin with, as GTK applications can run under different platforms or windowing systems.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 ebassi