1

The code setup is as follows:

  • Module ui_theme.py defines a theme and variant selector.
  • variant_selector has an on_change event handler.
  • Module cards_page.py imports ui_theme.py and has a handler on_variant_change.

Now, what I want to achieve that when ui_theme.on_change event is invoked then it should somehow call the cards_page.on_variant_change event.

Constraint: I definitely do not want to create a function to generate variant_selector. That makes the code-org bit messy. I also, can not post initialization, set the event handler.

My current solution is as follows:

  • ui_theme.py
on_change_variant_callback = None
def on_change_variant_click(dbref, msg, to_ms):
    print ("button clicked:", msg.value)
    if on_change_variant_callback:
        on_change_variant_callback(dbref, msg, to_ms)
        
    pass
  • in cards.py
import ui_theme
def on_variant_select():
  pass

ui_theme.on_change_variant_callback = on_variant_select

Seems to me that there should be a better way -- probably this where dependency injection can help, although i don't understand that concept well enough.

2 Answers 2

0

You can make your code more modular and flexible by using dependency injection. With this method, you provide the components a object needs from outside the object. Thus, you can loosen the close relationships between modules and make your code easier to manage, making it more open to future changes.

In your current situation, you have defined an on_change_variant_callback function in the ui_theme.py file and assigned a value to this callback function in the cards_page.py file. This situation creates a quite tight bond between the two files.

We can use dependency injection to loosen this tight bond. That is, we can convey the on_change_variant_callback function to the ui_theme.py module from outside in some way. Thus, we reduce the dependency between the ui_theme.py and cards_page.py files, making our code have a more modular and flexible structure.

With this method, you can more easily adapt to the future development of your code and easily adapt to possible changes

ui_theme.py

class VariantSelector:
def __init__(self, on_change_callback=None):
    self.on_change_callback = on_change_callback

def on_change_variant_click(self, dbref, msg, to_ms):
    print("button clicked:", msg.value)
    if self.on_change_callback:
        self.on_change_callback(dbref, msg, to_ms)

cards_page.py

from ui_theme import VariantSelector

def on_variant_select(dbref, msg, to_ms):
# Handle the variant change event
pass

variant_selector = VariantSelector(on_change_callback=on_variant_select)
0

You could create a listener and initialize that in the CardsPage class.

# ui_theme.py
class ThemeVariantListener:
    def __init__(self):
        self.on_change_variant_callback = None

    def set_variant_change_callback(self, callback):
        self.on_change_variant_callback = callback

    def on_change_variant_click(self, dbref, msg, to_ms):
        print("button clicked:", msg.value)
        if self.on_change_variant_callback:
            self.on_change_variant_callback(dbref, msg, to_ms)

# cards_page.py
import ui_theme

class CardsPage:
    def __init__(self):
        self.theme_listener = ui_theme.ThemeVariantListener()

    def on_variant_select(self, dbref, msg, to_ms):
        # Your logic for variant selection
        pass

    def initialize(self):
        self.theme_listener.set_variant_change_callback(self.on_variant_select)

# main.py
from cards_page import CardsPage

def main():
    cards_page = CardsPage()
    cards_page.initialize()

    # Now, you can use ui_theme.py and set its variant change callback
    ui_theme_instance = cards_page.theme_listener
    # Here, you can pass ui_theme_instance to wherever needed in your application
    # For example:
    # some_module.setup_ui_theme(ui_theme_instance)

if __name__ == "__main__":
    main()

Not the answer you're looking for? Browse other questions tagged or ask your own question.