I am working on a side project which entails a main process that spawns an HTTP server that keeps listening for events and handles them within an infinite loop.
This works as intended and I am now trying to add support for the start and stops of all the components from an icon in the system tray. For this, I am using Pystray which provides a run_detached method that should allow the icon loop to run on a separate thread.
The problem is that when I run the application the icon is created correctly, but as soon as I click on the icon menu to start the main process, the icon is not usable anymore. Right clicks are not detected and no further interactions are possible.
A small example that resembles my use case:
from PIL import Image, ImageDraw
import pystray
import time
class MyClass:
def __init__(self) -> None:
self.__running = False
def run(self):
while self.__running:
time.sleep(1)
print("running")
def change_running_state(self):
print(f"Running: {self.__running}")
self.__running = not self.__running
print(f"Running: {self.__running}")
if __name__ == "__main__":
def create_image(width, height, color1, color2):
image = Image.new('RGB', (width, height), color1)
dc = ImageDraw.Draw(image)
dc.rectangle(
(width // 2, 0, width, height // 2),
fill=color2)
dc.rectangle(
(0, height // 2, width // 2, height),
fill=color2)
return image
def start():
print("start")
cl.change_running_state()
cl.run()
def stop():
print("stop")
cl.change_running_state()
def exit_program():
print("exit")
import os
cl.change_running_state()
icon.stop()
os._exit(1)
icon = pystray.Icon(name = 'Doata2RuneRemainder', icon=create_image(64, 64, 'black', 'white'), menu=pystray.Menu(
pystray.MenuItem("Start", start),
pystray.MenuItem("Stop", stop),
pystray.MenuItem("Exit", exit_program),
))
cl = MyClass()
icon.run_detached()