Search code examples
pythongtkglade

GTK, Glade and Python connecting Handlers from Multiple Classes with the connect_signals


I hope you are all having a great day!

I can not figure out for the life of me how I can link Multiple Class Handlers to a window object with connect_signals(obj_or_class). I would like to have both classes Overview and Navigation injected into the window. Pondered adding each window and then searching through each class to generate it into a dictionary is viable...but is there an easier way to do it?!

I am OK with python but not the best. So any direction and explanations and help would be an asset! Thank you in advance.

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

class Application():
    def __init__(self):
        self.new_window = Window('overview')
        self.run()

    def run(self):
        Gtk.main()
        print('program terminated')

class Window():
    def __init__(self, window):
        self.gladefile = os.path.dirname((os.path.dirname(os.path.abspath(__file__))) 
            + '/overview/overview.glade')
        self.builder = Gtk.Builder()
        self.builder.add_from_file(self.gladefile)
        self.builder.connect_signals(Overview())
        self.window_name =  'overview'
        self.window = self.builder.get_object(self.window_name)
        self.window.show()

class Overview():
    def onDestroy(self, *args):
        Gtk.main_quit()

    def click(self, button):
        print("clicked")

class Navigation():
    def Overview(self, button):
        # Open the Overview Window
        print("clicked")

    def Settings(self, button):
        # Open the Settings Window
        print("clicked")

    def PID Settings(self, button):
        # Open the PID Settings Window
        print("clicked")

    def Reporting(self, button):
        # Open the Reporting Window
        print("clicked")

# Run Server
if __name__ == '__main__':
main = Application()

Solution

  • To do that you need to connect object's signals with handler separately instead of Gtk.Builder.connect_signals().

    Have look at below example.

    example.glade

      <?xml version="1.0" encoding="UTF-8"?>
      <interface>
        <!-- interface-requires gtk+ 3.0 -->
        <object class="GtkWindow" id="window1">
          <property name="can_focus">False</property>
          <signal name="destroy" handler="onDestroy" swapped="no"/>
          <child>
            <object class="GtkButton" id="button1">
              <property name="label" translatable="yes">button</property>
              <property name="use_action_appearance">False</property>
              <property name="visible">True</property>
              <property name="can_focus">True</property>
              <property name="receives_default">True</property>
              <property name="use_action_appearance">False</property>
              <signal name="pressed" handler="onButtonPressed" swapped="no"/>
            </object>
          </child>
        </object>
      </interface>
    

    example.py

    import gi
    gi.require_version('Gtk', '3.0')
    from gi.repository import Gtk
    
    class Handler:
        @staticmethod
        def onDestroy(*args):
            Gtk.main_quit()
    
    class Handler1:
        @staticmethod
        def onButtonPressed(button):
            print("Hello World!")
    
    builder = Gtk.Builder()
    builder.add_from_file("example.glade")
    window = builder.get_object("window1")
    window.connect("destroy",Handler.onDestroy)
    button = builder.get_object("button1")
    button.connect("pressed",Handler1.onButtonPressed)
    window.show_all()
    
    Gtk.main()