Search code examples
pythongtk

How to structure GUI event handler in Python


I have been having issues in designing my code in a way that doesn't create circular imports.

I have an event handler file that looks as such:

import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
import gui

class Gui_Event_Handler:
    def exit(self, *args):
        Gtk.main_quit()
    
    def drawmap(self, viewport, args):
        gui.draw_map()

Meanwhile, I create an object of that class in my GUI file to connect signals.

from gui_event_handler import Gui_Event_Handler

glade_file = "gui.glade"
builder = Gtk.Builder()
builder.add_from_file(glade_file)
builder.connect_signals(Gui_Event_Handler())

viewport = builder.get_object("view")

default_lat, default_lon = config.get_config("default loc")
current_lat, current_lon = get_coordinates()
zoom = int(config.get_config("default zoom"))
figure = get_figure(default_lat, default_lon, zoom)

viewport.add(FigureCanvas(figure))

window = builder.get_object("main_window")
window.show_all()
Gtk.main()

def draw_map():
    print("test")

Of course, this creates an error stating that the module is partially initialized due to circular imports.

After looking at various Stack Overflow posts about avoiding circular imports I tried using just

import gui_event_handler

This did not fix the issue of the circular import and even if it did, it doesn't help with the poor design I created.

I have tried making the GUI module use an object as well as having a main/imports file that runs both. Neither of them fixes the issue. The draw map method that I have done a print statement will call the draw method of the viewport to update it (I think that is the right method, I am still learning Gtk), I just have the print to test the structure which doesn't work.

I know the issue is that I have two files that call methods/classes in each other, but with my current knowledge of Python, I don't know how to structure everything.

How do I reorganize my methods and project so that I can update my GUI with a method call?


Solution

  • I was able to do more research for similar issues and found a solution that gave me enough guidance to achieve my goal.

    What I ended up doing that worked for what I was trying to achieve is moving the Gui_Event_Handler class to the same file as the rest of the GUI functions but below the defined functions.

    Where I had gui.py and gui_event_handler.py before, I now just have a gui.py which looks like the following:

    import gi
    gi.require_version("Gtk", "3.0")
    from gi.repository import Gtk
    
    builder = Gtk.Builder()
    
    def drawmap():
        #draw the map
    
    def exit():
        #exit the app
    
    class Gui_Event_Handler:
    
         def exit(self, *args):
              exit()
    
         def drawmap(self, *args):
              drawmap()
    
    builder.connect_signals(Gui_Event_Handler())
    Gtk.main()
    

    The methods within Gui_Event_Handler correspond with methods configured to be called by various signals in Glade.