moses-palmer/pystray

icon.stop doesn't works when run is given the parameter setup. It works just fine otherwise under similar conditions except the setup parameter.

avinash-550 opened this issue · 3 comments

#to stop entire program
def **quit_window**(icon, item):

    #stop the running icon
    icon.stop()

#classes
class Icon_class():
    def __init__(self):
        #open image
        self.image = Image.open("icon_image.png")
        
        #create option menu to quit systray icon
        self.menu=(item('Quit', **quit_window**),)
        
        #create icon
        self.icon=Icon("name", self.image, "Battery notifier", self.menu)
        
    def run_icon(self):
        #run icon
        **self.icon.run_detached(setup = change_ui)**

platform - windows 10
python 3.8x

Other information - change_ui function runs infinitely.

I'm working on Linux but I believe I have the same problem. The setup function is started in a new thread, and that function has to exit before icon.stop() can work.

In my case, the function has a loop where it runs time.sleep(5). Solution is to replace this with threading.Event().wait()...

def event_loop(icon):
    """Update the status every 5 seconds
    """
    # This provides an interruptable timer
    icon.timeout = threading.Event()

    # We always need to do this...
    icon.visible = True

    while True:
        if icon.timeout.wait(timeout=5):
            # We were rudely interrupted - exit!
            return

        print("Updating status...")

Now to interrupt the thread and exit the main loop, put this in the "Quit" menu item callback:

icon.timeout.set()
icon.stop()

If this is a generally useful pattern, maybe it can be added to the docs?

Thank you for your report.

Stopping blocking until the setup function returns is expected behaviour, but I realise that it is not clearly stated.

On the master branch the documentation has been updated, and a workaround with a timeout and a warning log has been added.