Python Forum
Issue referencing new instance from other class - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: Issue referencing new instance from other class (/thread-28685.html)



Issue referencing new instance from other class - nanok66 - Jul-30-2020

Hi all,

I have a large program that I distilled down hopefully to the bare issue that I am having. I have a GUI button that starts a thread. This thread would be started and stopped many times so it is necessary to create a new instance each time the button is pressed. My issue is that I am not sure how to pass the newly created instance back to my button callback. The callback only works the first time, but after the new instance is created the button cannot shut it off or even correctly reference the actual instance running the thread.

I'm sorry the code does not compile (or has something else wrong or missing), I just tried my best to cut away all unnecessary code to illustrate my current problem.

class MainPage(Page):
    def __init__(self, *args, **kwargs):
        Page.__init__(self, *args, **kwargs)

    self.heating_btn = tk.Button(self, text="Thermostat OFF", command=self.heatCallback)
    self.heating_btn.grid(row=0, column=0)

    def heatCallback(self):
        if h.isRunning:        # error is here, new instance is created in HeatingController class (heating_instance) and I am using wrong instance here to check if it’s running
            print(“Heating already started”)
        else:
            h.startHeating()


class HeatingController(Thread):
    def __init__(self, main_instance):
        Thread.__init__(self)
        self._running = False
        self.main_instance = main_instance
   
    @property
    def isRunning(self):
        return self._running

    @isRunning.setter
    def isRunning(self, value):
        self._running = value
    

    def run(self):
        # some code
        # more code
        self._running = False

    def startHeating(self):
        if self._running:
            print("Heating already started")
        else:
            heating_instance = HeatingController(self.main_instance)
            heating_instance.isRunning = True
            heating_instance.start()



if __name__ == "__main__":
    main = MainPage(root)
    h = tempController.HeatingController(main)
    GPIO.add_event_detect(raspberryGPIO.startButton, GPIO.RISING, callback=run_instance.startCycleCallback, bouncetime=2000)



RE: Issue referencing new instance from other class - deanhystad - Jul-30-2020

Can the button callback be responsible for making the thread? If not it sounds like you need an intermediary, somebody who knows about the current thread and provides a function for doing whatever the button needs to do. This could be a class method of your thread creator class (Heating Control), or a completely separate class designed to manage the interaction between GUI and threads.


RE: Issue referencing new instance from other class - Larz60+ - Jul-30-2020

you need a way to communicate with your threads, (called messaging semaphore)
I'd suggest reading the following: Little Book of Semaphores
with this you can set up a means of communicating with threads individually


RE: Issue referencing new instance from other class - nanok66 - Jul-31-2020

@deanhystad Yeah the intermediary sounds like the way I need to go because it is a bit more complicated than making the button responsible for making the thread, but I accidentally cut that code out trying to make it easy to read for y'all. Thanks for the advice as always.

@Larz60+ Cool I haven't even heard of semaphores yet. Thanks for introducing me to the idea! Once I read into it maybe that'll be the fix.