Reputation: 155
I have a tkinter app that hides itself in the system tray when closed (X) , and keeps running in the background, I can also bring back the app from hidden tray to the front if I want, and this code works perfectly fine for that. However, there is a complex issue I want to resolve. I want my app to have the same behaviour when it is reopened from outside hidden tray. from shortcut.exe e.t.c. But it opens another instance.
I realized that I only need to do what show_window_action method does normally. But how can I bring that system tray icon back to execute it from newly opened instance?
from PIL import Image, ImageTk
import pystray
class App:
def __init__(self):
self.root = Tk()
#rest of my code
...
self.root.protocol("WM_DELETE_WINDOW", self.hide_window)
def show_window_action(self, icon, item):
self.system_tray_icon.stop()
self.root.deiconify()
image = Image.open("hrm.ico")
self.menu = (pystray.MenuItem('Quit', self.quit_window), pystray.MenuItem('Show', self.show_window_action))
self.menu = [item for item in self.menu if item.text != 'Quit']
self.system_tray_icon = pystray.Icon("name", image, "Edbox Tracker", self.menu)
def hide_window(self):
image = Image.open("hrm.ico")
self.system_tray_icon = None
self.system_tray_icon = pystray.Icon("name", image, "Edbox Tracker", self.menu)
self.root.withdraw()
self.system_tray_icon.run()
Upvotes: 2
Views: 78
Reputation: 47173
You can create the menu inside __init__()
instead of inside show_window_action()
.
Below is the modified code with missing parts:
from tkinter import *
from PIL import Image
import pystray
class App:
def __init__(self):
self.root = Tk()
# create the icon image and the menu
self.image = Image.open("hrm.ico")
self.menu = pystray.Menu(
pystray.MenuItem('Quit', self.quit_window),
pystray.MenuItem('Show', self.show_window_action, default=True, visible=False)
)
self.root.protocol("WM_DELETE_WINDOW", self.hide_window)
def mainloop(self):
self.root.mainloop()
def quit_window(self):
self.system_tray_icon.stop()
self.root.destroy()
def show_window_action(self, icon, item):
self.system_tray_icon.stop()
self.root.deiconify()
def hide_window(self):
self.system_tray_icon = pystray.Icon("name", self.image, "Edbox Tracker", self.menu)
self.root.withdraw()
self.system_tray_icon.run()
App().mainloop()
Note that I would suggest App
inherits from Tk
instead of creating the root window inside __init__()
.
Upvotes: 2