This library allows you to create a system tray icon.
Supported platforms are Linux under Xorg, GNOME and Ubuntu, macOS and Windows.
See here for the full documentation.
License: GNU General Public License v3.0
This library allows you to create a system tray icon.
Supported platforms are Linux under Xorg, GNOME and Ubuntu, macOS and Windows.
See here for the full documentation.
i have a very simple pystray program wich simply generates an image from a number and displays it in the tray however when using pyinstaller to compile it wich works with no errors. Then when i run it i get the error
Traceback (most recent call last):
File "counter.py", line 1, in <module>
File "c:\users\spitf\appdata\local\programs\python\python37\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 623, in exec_module
exec(bytecode, module.__dict__)
File "site-packages\pystray\__init__.py, line 48, in <module>
File "site-packages\pystray\__init__.py, line 45, in backend
ImportError: this platform is not supported: No module named "pystray._win32"
[129696] Failed to execute script counter
line 1 is import pystray
The error flashes up quickly the dissapears so ive tried my best to copy it down.
I am using windows 10 64 bit python 3.7 and pystray 0.16.0.
I have checked the site-packages folder and _win32 is there and i have pywin32 installed and the code works perfectly when not compiled. Any help would be appreciated
On calling the method pystray.MenuItem() with the argument submenu one would get the following error:
TypeError: init() got an unexpected keyword argument 'submenu'
I have taken a look in the file _base.py which implements the above mentioned method and could not find any argument with the name submenu. Also there is no place where the method submenu is called...
Maybe this is also a misunderstanding but with the documentation I am not able to get this to work.
_util.win32
pystray never checks if the imported Gtk-class works like it tries in the xorg-class.
This means that projects like FlexGet crashes running headless on a machine where Gtk3 is installed: Flexget/Flexget#2633
The following logic is tested on both headless and desktop system.
The code however is only tested with flexget on a headless system.
So not proposed, needs more testing.
--- a/lib/pystray/_gtk.py
+++ b/lib/pystray/_gtk.py
@@ -24,6 +24,8 @@ from gi.repository import Gtk
from ._util.gtk import GtkIcon, mainloop
from ._util import serialized_image
+if not Gtk.init_check()[0]:
+ raise Exception("Gtk could not initialize")
class Icon(GtkIcon):
def __init__(self, *args, **kwargs):
When explorer.exe
(who is responsible for drawing Notification Area) restarts (i.e. after crash) icons of most applications shown, but not for pystray. I've found that there are specific message (TaskbarCreated
) sent in this case. There are one problem - it's only broadcasted to top-level windows, so notification-only windows (with parent HWND_MESSAGE) doesn't receive it.
Finally: I've got a PR for this: #10
I put a pystray icon in my class:
import pystray
from PIL import Image
class MyIcon(object):
def __init__(self):
self.ico = Image.new('RGB', (16, 16), 'green')
self.menu = pystray.Menu(pystray.MenuItem('Quit', self.quit))
self.icon = pystray.Icon('TRAY', self.ico, 'title', self.menu)
def run(self):
self.icon.run()
def quit(self, icon, item):
# do something with self
self.icon.stop()
myico = MyIcon()
myico.run()
I got an error on execution. It seems I cannot put bounded class method in the menu.
Traceback (most recent call last):
File "D:\tmp\python\icon_test.py", line 17, in <module>
myico = MyIcon()
File "D:\tmp\python\icon_test.py", line 7, in __init__
self.menu = pystray.Menu(pystray.MenuItem('Quit', self.quit))
File "C:\Python27\lib\site-packages\pystray\_base.py", line 318, in __init__
self._action = self._assert_action(action)
File "C:\Python27\lib\site-packages\pystray\_base.py", line 428, in _assert_action
raise ValueError(action)
ValueError: <bound method MyIcon.quit of <__main__.MyIcon object at 0x00000000045EC358>>
But if I remove the item
argument from my class method like this:
def quit(self, icon):
# do something with self
self.icon.stop()
The icon can be started on the tray, but once the quit menu is clicked an exception raise showing that my quit()
method got too many arguments
ERROR:pystray._base:An error occurred when calling message handler
Traceback (most recent call last):
File "C:\Python27\lib\site-packages\pystray\_win32.py", line 378, in _dispatcher
uMsg, lambda w, l: 0)(wParam, lParam) or 0)
File "C:\Python27\lib\site-packages\pystray\_win32.py", line 198, in _on_notify
descriptors[index - 1](self)
File "C:\Python27\lib\site-packages\pystray\_base.py", line 240, in inner
callback(self)
File "C:\Python27\lib\site-packages\pystray\_base.py", line 327, in __call__
return self._action(icon, self)
TypeError: quit() takes exactly 2 arguments (3 given)
So, is there a way to make pystray working with my class?
Is there any way to update the icon while its running? I've tried so hard but couldn't find any way to update it. I'm currently trying to code a CPU indicator. Here's my code:
import psutil
import pystray
from PIL import Image, ImageDraw, ImageFont
from threading import Thread
font = ImageFont.truetype('arial.ttf', 75)
def setup(icon):
icon.visible = True
def exit_action(icon):
icon.visible = False
icon.stop()
def refresh_images():
global blue_img
blue_img = Image.new('RGB', (100, 100), color=(0, 0, 255))
global red_img
red_img = Image.new('RGB', (100, 100), color=(255, 0, 0))
def decide_bg(usage):
if usage > 60:
return red_img
else:
return blue_img
def decide_coords(usage):
if usage < 10:
return (32, 5)
elif usage == 100:
return (0, 5)
else:
return (5, 5)
def init_icon():
usage = int(psutil.cpu_percent(interval=1))
refresh_images()
image = decide_bg(usage)
coords = decide_coords(usage)
d = ImageDraw.Draw(image)
d.text(coords, str(usage), font=font, fill=(255, 255, 255))
icon = pystray.Icon("usage", icon=image, title="CPU Usage")
icon.menu = pystray.Menu(pystray.MenuItem('Exit', lambda : exit_action(icon)))
icon.run()
thread = Thread(daemon=True, target=init_icon())
Simply, I need to find a way to update the icon each second, to be able to show the current CPU usage. I'm quite new to Python and I'd truly appreciate some help. Thanks in advance.
Hello, Moses!
I've been developing on pystray for a little bit now and was excited to see the additions of notifications! That being said, I've tried to display one on Windows 10 (Notifications enabled) and HAS_NOTIFICATION is returning false! My code is below, perhaps I'm approaching it wrong?
import pystray
from PIL import Image
import io, base64
DEFAULT_BASE64_ICON = b'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'
def on_clicked(icon, item):
if (icon.HAS_NOTIFICATION):
icon.notify("Hey!")
else:
print("WAT")
class SystemTray:
def create_image(self, b64):
buffer = io.BytesIO(base64.b64decode(b64))
img = Image.open(buffer)
return img
def __init__(self):
self.MenuItems = []
self.MenuItems.append(pysItem("Test", on_clicked))
self.TrayIcon = pystray.Icon("Title", self.create_image(DEFAULT_BASE64_ICON))
self.TrayIcon.menu = self.MenuItems
self.TrayIcon.run()
SystemTray()
Thank you!
Help me , please , to find the proper pair of pystray/PIL version working on WinXPsp3 with Python 3.4 !
...'cause I'he got WinError messages - a lot. I'he tried to 'fix' the problem modifying lines in _win32.py module . Like this:
with serialized_image(self.icon, 'BMP') as icon_path:
self._icon_handle = win32.LoadImage(
None,
icon_path,
0,
16,
16,
win32.LR_LOADFROMFILE )
...but if I eliminate one error , I get the next one :) , like this:
Traceback (most recent call last):
File "C:\Python34\lib\threading.py", line 911, in _bootstrap_inner
self.run()
File "C:\Python34\lib\threading.py", line 859, in run
self._target(*self._args, **self._kwargs)
File "C:\Python34\NTPMON.pyw", line 44, in TRAY
icon.visible=True
File "C:\Python34\lib\site-packages\pystray_base.py", line 143, in visible
self._show()
File "C:\Python34\lib\site-packages\pystray_win32.py", line 76, in _show
szTip=self.title)
File "C:\Python34\lib\site-packages\pystray_win32.py", line 270, in _message
**kwargs))
File "C:\Python34\lib\site-packages\pystray_util\win32.py", line 192, in _err
raise ctypes.WinError()
OSError: [WinError 0]
Thanks for Your help !
icon.menu.items is tuple type. How can i change items title? I need to update the title items in the process of running my application
update_menu is meant to be called from the setup thread, but is currently unsafe to use on macOS/win32, since the main thread may be updating the menu at the same time. In addition, Cocoa requires that UI functions be called from the main thread.
Both implementations of _update_menu need to be changed to pass a message to the main thread, and do the real menu updates there.
macOS has similar problems with update_icon and update_title, and the win32 update_icon implementation should be reviewed as well (update_icon looks safe).
#59 fixed this for the GTK backend.
Hi, first thanks for this easy to use tray icon!
I'm not sure if this is a bug or I didn't understand the parameter for name and title.
But if I hover over the icon, it only shows the name of the file not the title or name I assigned in the icon function.
I'm running KDE 5 and I forced to import Icon from _gtk (When using ._appindicator the default click won't work).
Thanks.
Hi.
Although one menu item of mine has the default
flag set, nothing happens when I click on the icon.
I construct it like so:
menu = (item(localize('Open Type.World App'), openApp, default=True), item(localize('Check for font updates now'), checkForUpdates))
icon = pystray.Icon("Type.World", image, "Type.World", menu)
Is more code needed? This is how I understood it works.
(The default menu item does get rendered in bold in the menu, so something is happening for sure)
Hi,
I have a Menu as below for "Login". When the variable "loggedin" changes to True, neither with nor without update_menu(), the menu is not changing to "Logout". Any ideas please?
def on_monitor(icon, item):
global state,loggedin
state = not item.checked
url = 'www.example.com'
webbrowser.open_new_tab(url + '?i=' + str(uuid.uuid4()) )
print("Waiting for login to complete")
loggedin = True
print("Logged In",icon.update_menu())
icon = pystray.Icon('Sample',title="Icons",menu=Menu(
MenuItem(('Logout' if loggedin else 'Login'),on_monitor),
MenuItem('Settings',on_settings),
MenuItem('Sync',on_sync,checked=lambda item: state1),
MenuItem('Exit',on_exit,checked=lambda item: state2)))
Hi, I'm trying the next example, taken from here, and when I click the icon, the menu is not appearing. I have also try some very simple variation, but I don't know why the menu doesn't appear. I don't see any errors in my terminal, seems to be running fine. I've checked the documentation, but it seems like it should work right away.
from PIL import Image, ImageDraw
from pystray import Icon, Menu as menu, MenuItem as item
def image(color1, color2, width=64, height=64):
result = Image.new('RGB', (width, height), color1)
dc = ImageDraw.Draw(result)
dc.rectangle((width // 2, 0, width, height // 2), fill=color2)
dc.rectangle((0, height // 2, width // 2, height), fill=color2)
return result
def on_activate(icon, quit):
if quit:
print('stopping...')
icon.stop()
else:
print('doing nothing...')
def setup(icon):
icon.visible = True
icon = Icon(
'test',
icon=image('white', 'black'),
menu=menu(
item(
'Print',
lambda icon: on_activate(icon, False)),
menu.SEPARATOR,
item(
'Quit',
lambda icon: on_activate(icon, True))))
icon.run(setup)
This is my system:
--------------------------------
OS: Ubuntu 17.10 x86_64
Host: Precision 5520
Kernel: 4.13.0-35-generic
Shell: bash 4.4.12
Resolution: 2048x1152
DE: GNOME
WM: GNOME Shell
WM Theme: Ambiance
Theme: Adapta [GTK2/3]
Icons: Numix-Circle [GTK2/3]
CPU: Intel i7-7700HQ (8) @ 3.800GHz
GPU: Intel HD Graphics 630
GPU: NVIDIA Quadro M1200 Mobile
Memory: 9144MiB / 32018MiB
Thanks a lot!
Love this library, have just used it to speed up my development of a project. That said there are some holes in the submenu documentation. I understand you have no obligation to fix this, just thought I would put this forward for you to change at your discretion.
Submenus could use some clarification. I think it should be mentioned that you have to pass a Menu object in as the action of a menu item. Also adding submenu example code would be nice.
Hi,
When I use xorg tray icon, there is system tray icon but only with 1 pixel width. After digging I found that xembed windows with systray icon should contain size hints, something like
window.set_wm_normal_hints(
flags=(Xlib.Xutil.PPosition | Xlib.Xutil.PSize | Xlib.Xutil.PMinSize),
min_width=24,
min_height=24
)
On Gtk icon. In you documentation is firstly created Icon() object without icon, which is set latter:
import pystray
icon = pystray.Icon('test name')
image = ...
icon.icon = image
This doesn't work (systray icon is not shown), because icon is not really set (_update_icon()
) while visible
is False
, but one cannot set visible
to True
, until some image data are provided. Documentation tells to call show()
, but Icon
object has not show()
method.
All works as expected, when i pass image
into constructor, or when i set image twice, eg.::
icon.icon = image
icon.visible = True
icon.icon = image
or when i call _update:icon()
:
icon.icon = image
icon.visible = True
icon._update_icon()
Both workarounds are ugly.
I tried the following code:
import pystray
import sys
import time
from PIL import Image
from pystray import Menu, MenuItem
def exit_action(icon):
icon.visible = False
sys.exit(0)
def init_icon():
icon = pystray.Icon('mon')
icon.menu = Menu(
MenuItem('Exit', lambda : exit_action(icon)),
)
icon.icon = Image.open('icon.ico')
icon.title = 'tooltip'
def setup(icon):
icon.visible = True
icon.run(setup)
return icon
icon = init_icon()
while True:
time.sleep(5)
When I click on Exit menu item from the system tray menu Python shows exception instead of termination of the program:
An error occurred when calling message handler
Traceback (most recent call last):
File "C:\Python34\lib\site-packages\pystray\_win32.py", line 377, in _dispatcher
uMsg, lambda w, l: 0)(wParam, lParam) or 0)
File "C:\Python34\lib\site-packages\pystray\_win32.py", line 197, in _on_notify
descriptors[index - 1](self)
File "C:\Python34\lib\site-packages\pystray\_base.py", line 236, in inner
callback(self)
File "C:\Python34\lib\site-packages\pystray\_base.py", line 320, in __call__
return self._action(icon, self)
File "C:\Python34\lib\site-packages\pystray\_base.py", line 408, in wrapper0
return action()
File "C:\insolor\ะะพะฝะธัะพัะธะฝะณ\pstray_test.py", line 15, in <lambda>
MenuItem('Exit', lambda : exit_action(icon)),
File "C:\insolor\ะะพะฝะธัะพัะธะฝะณ\pstray_test.py", line 9, in exit_action
sys.exit(0)
SystemExit: 0
After the exception the Python instance is still hanging in the task manager.
So how to terminate a program from the system tray menu?
System: Windows 10 Home (64 bit, ver 1511, build 10586.839)
Python 3.4.4 (v3.4.4:737efcadf5a6, Dec 20 2015, 20:20:57) [MSC v.1600 64 bit (AMD64)] on win32
I'm getting this exception when I try to run an instance of pystray.
Iยดm creating a quit option that joins a thread and then does a sys.exit, what happens is this:
An error occurred when calling message handler
Traceback (most recent call last):
File "C:\Python38\lib\site-packages\pystray\_win32.py", line 377, in _dispatcher
return int(icon._message_handlers.get(
File "C:\Python38\lib\site-packages\pystray\_win32.py", line 198, in _on_notify
descriptors[index - 1](self)
File "C:\Python38\lib\site-packages\pystray\_base.py", line 241, in inner
callback(self)
File "C:\Python38\lib\site-packages\pystray\_base.py", line 328, in __call__
return self._action(icon, self)
File "C:\Python38\lib\site-packages\pystray\_base.py", line 420, in wrapper0
return action()
File "tray3.py", line 42, in <lambda>
item("Exit", lambda: make_me_stop())
File "tray3.py", line 20, in make_me_stop
sys.exit()
SystemExit
This is the code I'm working on:
import pystray
from PIL import Image
from pystray import MenuItem as item
import time
import sys
import threading
makemestop=False
icon="16/002-moon.png"
# the function to quit the program
def make_me_stop():
print("I'm trying to stop")
global makemestop
makemestop=True
my_x.join()
icon.stop()
print("I STOPPED!")
sys.exit()
# This must go into another thread
def myloop():
try:
global icon
icon="16/001-sun.png"
while makemestop==False:
print("I won't stop - ", makemestop)
time.sleep(1)
except:
print("yass... I really stopped")
# this is the main thread
if __name__=="__main__":
my_x=threading.Thread(target=myloop)
my_x.start()
image=Image.open(icon)
menu=(
item("Options", lambda: print("Call options")),
item("Exit", lambda: make_me_stop())
)
icon=pystray.Icon("My icon title", image, "My icon title", menu)
icon.run()
I found on documentation:
HAS_DEFAULT_ACTION = True
Whether this particular implementation has a default action that can be invoked in a special way, such as clicking on the icon.
https://pythonhosted.org/pystray/
But how can I define a default action to a pystray Icon?
When I click 2 times (double-click) on the tray icon, python console gets this error:
An error occurred when calling message handler Traceback (most recent call last): File "C:\Users\Matheus\PycharmProjects\limaApp\venv\lib\site-packages\pystray\_win32.py", line 377, in _dispatcher return int(icon._message_handlers.get( File "C:\Users\Matheus\PycharmProjects\limaApp\venv\lib\site-packages\pystray\_win32.py", line 175, in _on_notify self() File "C:\Users\Matheus\PycharmProjects\limaApp\venv\lib\site-packages\pystray\_base.py", line 84, in __call__ self._menu(self) TypeError: 'tuple' object is not callable
Here is my entire and simple App code:
from pystray import MenuItem as item
import pystray
from PIL import Image
import tkinter as tk
def quit_window(icon, item):
icon.stop()
window.destroy()
def show_window(icon, item):
icon.stop()
window.after(0, window.deiconify)
window = tk.Tk()
window.title("My App")
image = Image.open("assets/images/icon.ico")
menu = (item('My App', show_window, default=True), item('Sair', quit_window))
icon = pystray.Icon("name", image, "My App", menu)
icon.run()
def withdraw_window():
print('Close window')
window.withdraw()
window.protocol('WM_DELETE_WINDOW', withdraw_window)
window.mainloop()
Anyone can help me?
I would like to run update_menu()
when the menu is opened.
I'm using a few of the menu items purely to display data - one of them is a filesize indicator. Currently the best way I've found is to just update the data every few seconds, but this isn't ideal and causes some responsiveness issues.
Is there an easy way of doing this?
The code in https://pystray.readthedocs.io/en/latest/usage.html#displaying-notifications provokes an error on Mate Desktop:
AttributeError: 'Icon' object has no attribute 'remove_notification'
Maybe this is a bug?
Hello !
I try to have a menu item that call a close function.
But, the only thing that seems to be called in my close()
function : trayicon.visible = False
and trayicon.stop()
The sys.exit(0)
call is not call.
There is something I do in the wrong way ?
My code :
import sys
import datetime
import pystray
from pynput import keyboard
from pystray import MenuItem as item
from PIL import Image
APP_NAME = 'ECS Shortcuts'
APP_VERSION = '1.0'
def shortcuts(trayicon):
trayicon.visible = True
current = set()
def on_press(key):
"""if any([key in COMBO for COMBO in COMBINATIONS]):
current.add(key)
if any(all(k in current for k in COMBO) for COMBO in COMBINATIONS):
listener.stop()"""
if key == keyboard.Key.f8:
execute()
def on_release(key):
"""if any([key in COMBO for COMBO in COMBINATIONS]):
current.remove(key)"""
pass
with keyboard.Listener(on_press=on_press,
on_release=on_release
) as listener:
listener.join()
def execute():
date = datetime.datetime.now()
day = date.day
month = date.month
if date.hour < 10:
hour = '0' + str(date.hour)
else:
hour = date.hour
if date.minute < 10:
minute = '0' + str(date.minute)
else:
minute = date.minute
kb = keyboard.Controller()
kb.type("%s %s/%s %sh%s : " % (user, day, month, hour, minute))
def close():
trayicon.visible = False
trayicon.stop()
sys.exit(0)
if __name__ == '__main__':
if len(sys.argv) > 1:
user = sys.argv[1]
else:
user = ''
name = ' '.join((APP_NAME, APP_VERSION))
icons = {
'default': Image.open('icon.png')
}
menu = (item('Quitter', close), )
trayicon = pystray.Icon(name=name,
icon=icons['default'],
menu=menu,
title=name
)
trayicon.icons = icons
trayicon.warnings = True
try:
trayicon.run(shortcuts)
except Exception as e:
pass
finally:
trayicon.stop()
sys.exit(0)
Thank in advance for any help,
Lucas
Hi,
can you please add to the readme which operating systems are supported? Thanks
Hello,
I am using pystray to show an icon on my desktop this icon has a Menu that has two MenuItems, My purpose is how to get text of clicked MenuItem.
thank you for help
Hi, it will be possible to add scroll possibilities over the tray icon? Like when you use your mouse wheel to scroll up over icon, then you volume goes up ... ect. Thanks for answer.
I get following error in making a windows app.
def setup(icon):
icon.visible = True
File "pystray_base.pyo", line 153, in visible
File "pystray_win32.pyo", line 70, in _show
File "pystray_win32.pyo", line 323, in assert_icon_handle
File "contextlib.pyo", line 17, in enter
File "pystray_util_init.pyo", line 42, in serialized_image
File "PIL\Image.pyo", line 1885, in save
KeyError: 'ICO'
Anyone faced this before?
Hello Moses,
Thanks for new addition to pystray, I appreciate your work,
I already put "pystray" in latest version of my application "PyIDM", everything works great
I downloaded pystray from github and used the example you supplied but couldn't display notification, maybe i am doing something wrong
I am running windows 8-32 bit with python 3.6-32 bit
I am not expert in win32 API, but I think there is something mentioned in plyer balloon tip notification regarding registering a class first
here is plyer balloontip.py link:
https://github.com/kivy/plyer/blob/master/plyer/platforms/win/libs/balloontip.py
Also plyer has managed to send notification in linux too, if somehow pystray can do this it will be a great hit
the code i tried:
from pystray import Icon as icon, Menu as menu, MenuItem as item
from PIL import Image
import io, base64
APP_ICON2 = b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAKfSURB\nVDiNZdNfaNVlHAbwz/n9zu/M6Vz7o41yzplg4BCFolbZWi2FiBIMvQq9qJAuCokugqCWFAgJxSgS\n+kN5Uxb9uVJyVgc0wgg65UpczLl2HHPacM7z23bmOaeLnU6bvlcP7/s8z/d5X94n4Ya1dz3Fp9GF\n1vLmORzDB3T3zWcn/oc9VYy/hd3tssEWAxrErgmNqpHW6he3FnAAL9Cdn2fQU8X4keXiB/f7Vrus\nvFBOSiwSi8wI9Wv0pvuMq/4ej9CdD+cM7n5nmXj7576wsTaW7HpIPEtuqiBXCORErkoJlHT420nN\nq6cl60kfSZTvnPnYN8H9hjR8ckDdzh3Ge08I6m7y444XXTw3VkmSkzItaZ9NBYINIQ+83C7b/pyT\n8ktqBW1trmROyzy7V76YkGxeIZs5WxHHIqGiCYuCC5bMJPHwFgPyQqWWVv2v9ohFZmvrrdy51eFt\nLy0Qz+HF1rvgd02bA7Q0mhKLXDo9VCHd/voembcPuThyuSKeSVXLlc+TirAqQOmaxHUTIi3bugxn\nzspJKdXVe+y9PfZPfqnj+a1zCQVQSmJ4VM26+eJYZOzUgMe/3mes/7zGtSt99cqnzvx23rK1K8Qi\n0VyC4SR6f7B63T2GK+JY5ND217Q8usn4pdip42dM5BOeeONJhw/+pEZev0Y4GtKZHbF090ajQaBU\nMbiSDwz+MWJ48B+ThVAssripwWQ+ITk0qNeaAp4JSY/RefOvbrmrw5BJVTe8x3+4r2/MnctnfTTS\nZEbyXboPln9i57Ep0b0/a75tg1GBksuqF4iXmtFs0ocjTSYs+g67SBfKBukCnZ9NiepPWHXHVVVB\nvWlVCiJFoZK/NDpqTWFusl3XlWlBndsoPoXN5TonMFiu8/t0/zmf/S9tcxBW9J/R4gAAAABJRU5E\nrkJggg==\n'
def create_image():
buffer = io.BytesIO(base64.b64decode(APP_ICON2))
img = Image.open(buffer)
return img
icon('test', create_image(), menu=menu(
item(
'With submenu',
menu(
item(
'Show message',
lambda icon, item: icon.notify('Hello World!')),
item(
'Submenu item 2',
lambda icon, item: icon.remove_notification()))))).run()
I just wanted to know if there is any way to open a tkinter window on left click on the tray !
Thank you
Sigma
hello,
Please help me, im using pystray to create an icon on my desktop, my purpose is how to change value of menuitem, i was thinking about stoping icon setup then updating icon menu before restart for a new time the icon setup. but i can't stop icon run, any idea please
Hi,
I'am trying to create an icon in the system tray using the provided example.
But here is my code:
from PIL import Image, ImageDraw
import pystray
print("Start")
icon = pystray.Icon('test name')
print("Step 1")
def create_image():
# Generate an image and draw a pattern
width=16
height=16
color1=50
color2=250
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)
image.show()
return image
icon.icon = create_image()
print("Step 2")
icon.run()
print("Step 3")
And the console output is:
Start
Step 1
Step 2
What am I doing wrong?
I'm trying to create a menu with 'checked' items dynamically using lambda and for statements.
In the code, I have a function that returns the menu with a sub-menu built based in a dictionary named 'menu_notifications_active'.
The problem occurring is the checked item is only updated when I switch the last item ('Item5'). The action code is called correctly, but the code for the 'checked' property, for some reason, is not working as expected.
My code:
from pystray import Icon as tray_icon, Menu as menu, MenuItem as item
menu_notifications_active = {'Item1': True, 'Item2': True,
'Item3': True, 'Item4': True, 'Item5': True}
def check_item(icon, item):
global menu_notifications_active
menu_notifications_active[item.text] = not item.checked
logger.info("Notification changed for {}: {}".format(
item.text, menu_notifications_active[item.text]))
def get_item_value(key):
logger.info("get_item_value('{}') = {}".format(
key, menu_notifications_active[key]))
return menu_notifications_active[key]
def create_menu():
tray_menu = menu(item('Notifications', menu(
lambda: (item(key, check_item, checked=lambda item: menu_notifications_active[key]) for key in menu_notifications_active))
), item('Exit', opt_exit))
return tray_menu
def main():
tray_icon.icon = create_image()
tray_icon.menu = create_menu()
sys.exit(0)
if __name__ == '__main__':
main()
In the logs we can see:
2019-07-25 12:55:23,345 [INFO] get_item_value('Item5') = True
2019-07-25 12:55:23,345 [INFO] get_item_value('Item5') = True
2019-07-25 12:55:23,345 [INFO] get_item_value('Item5') = True
2019-07-25 12:55:23,345 [INFO] get_item_value('Item5') = True
2019-07-25 12:55:23,345 [INFO] get_item_value('Item5') = True
2019-07-25 12:55:23,346 [INFO] get_item_value('Item5') = True
2019-07-25 12:55:23,346 [INFO] get_item_value('Item5') = True
2019-07-25 12:55:23,346 [INFO] get_item_value('Item5') = True
2019-07-25 12:55:23,346 [INFO] get_item_value('Item5') = True
2019-07-25 12:55:23,346 [INFO] get_item_value('Item5') = True
2019-07-25 12:55:23,347 [INFO] get_item_value('Item5') = True
2019-07-25 12:55:23,347 [INFO] get_item_value('Item5') = True
2019-07-25 12:55:23,347 [INFO] get_item_value('Item5') = True
2019-07-25 12:55:23,348 [INFO] get_item_value('Item5') = True
2019-07-25 12:55:23,348 [INFO] get_item_value('Item5') = True
2019-07-25 12:55:23,348 [INFO] get_item_value('Item5') = True
2019-07-25 12:55:23,348 [INFO] get_item_value('Item5') = True
2019-07-25 12:55:23,348 [INFO] get_item_value('Item5') = True
2019-07-25 12:55:23,348 [INFO] get_item_value('Item5') = True
2019-07-25 12:55:23,349 [INFO] get_item_value('Item5') = True
2019-07-25 12:56:41,182 [INFO] Notification changed for Item1: False
2019-07-25 12:56:41,182 [INFO] get_item_value('Item5') = True
2019-07-25 12:56:41,182 [INFO] get_item_value('Item5') = True
2019-07-25 12:56:41,182 [INFO] get_item_value('Item5') = True
2019-07-25 12:56:41,182 [INFO] get_item_value('Item5') = True
2019-07-25 12:56:41,182 [INFO] get_item_value('Item5') = True
2019-07-25 12:56:41,182 [INFO] get_item_value('Item5') = True
2019-07-25 12:56:41,182 [INFO] get_item_value('Item5') = True
2019-07-25 12:56:41,182 [INFO] get_item_value('Item5') = True
2019-07-25 12:56:41,182 [INFO] get_item_value('Item5') = True
2019-07-25 12:56:41,197 [INFO] get_item_value('Item5') = True
2019-07-25 12:57:20,437 [INFO] Notification changed for Item5: False
2019-07-25 12:57:20,437 [INFO] get_item_value('Item5') = False
2019-07-25 12:57:20,437 [INFO] get_item_value('Item5') = False
2019-07-25 12:57:20,437 [INFO] get_item_value('Item5') = False
2019-07-25 12:57:20,437 [INFO] get_item_value('Item5') = False
2019-07-25 12:57:20,437 [INFO] get_item_value('Item5') = False
2019-07-25 12:57:20,437 [INFO] get_item_value('Item5') = False
2019-07-25 12:57:20,437 [INFO] get_item_value('Item5') = False
2019-07-25 12:57:20,437 [INFO] get_item_value('Item5') = False
2019-07-25 12:57:20,437 [INFO] get_item_value('Item5') = False
2019-07-25 12:57:20,437 [INFO] get_item_value('Item5') = False
Thanks in advance!
Here my codes:
def quit_window(self):
self.icon.stop()
self.exitMain()
def show_window(self):
self.icon.stop()
self.mainWindow.after(0, self.mainWindow.deiconify)
keyboard.add_hotkey(self.keyShortcut, self.runRecongnizer)
def withdraw_window(self):
keyboard.unhook_all_hotkeys()
self.mainWindow.withdraw()
image = PIL.Image.open("resources/media/image/favicon.ico")
menu = (pystray.MenuItem(lang().translate("Show"), lambda: self.show_window()),
pystray.MenuItem(lang().translate("Exit"), lambda: self.quit_window()))
self.icon = pystray.Icon("name", image, "My Program", menu)
self.icon.run()
When I left-clicking the system tray icon, I get this error:
An error occurred when calling message handler Traceback (most recent call last): File "C:\Users\MEmin\AppData\Local\Programs\Python\Python35-32\lib\site-packages\pystray\_win32.py", line 378, in _dispatcher uMsg, lambda w, l: 0)(wParam, lParam) or 0) File "C:\Users\MEmin\AppData\Local\Programs\Python\Python35-32\lib\site-packages\pystray\_win32.py", line 175, in _on_notify self() File "C:\Users\MEmin\AppData\Local\Programs\Python\Python35-32\lib\site-packages\pystray\_base.py", line 83, in __call__ self._menu(self) TypeError: 'tuple' object is not callable
In the second code snippet,
from PIL import Image, ImageDraw
# Generate an image
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)
icon.image = image
change icon.image = image
to icon.icon = image
I am trying to run the sample app on Mac OS mojave. But I get the following error. The icon runs fine though. Can someone please help.
Error: 'Icon' object has no attribute '_delegate'
Traceback (most recent call last):
File "test.py", line ***
icon.update_menu()
File "/usr/local/lib/python3.7/site-packages/pystray/_base.py", line 213, in update_menu
self._menu_handle = self._create_menu_handle()
File "/usr/local/lib/python3.7/site-packages/pystray/_darwin.py", line 70, in _create_menu_handle
nsmenu = self._create_menu(self.menu, callbacks)
File "/usr/local/lib/python3.7/site-packages/pystray/_darwin.py", line 190, in _create_menu
self._create_menu_item(descriptor, callbacks))
File "/usr/local/lib/python3.7/site-packages/pystray/_darwin.py", line 219, in _create_menu_item
menu_item.setTarget_(self._delegate)
AttributeError: 'Icon' object has no attribute '_delegate'
Hi great project i really appreciate any modules that add basic functions to Python while keeping it cross-platform.
I'd like to "feature" request that you remove the dependency on PIL and allow for usage of an icon.png file. Hope i'm not alone in this desire, that it sounds reasonible and hope that it is easy to implement.
Kubuntu 20.04 (plasma)
(main.py:1070695): libappindicator-WARNING **: 19:01:17.474: Using '/tmp' paths in SNAP environment will lead to unreadable resources
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/gi/overrides/GLib.py", line 130, in _create
iter(value)
TypeError: 'int' object is not iterable
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/www/anbcoder/.venv/lib/python3.8/site-packages/pystray/_base.py", line 267, in inner
callback(self)
File "/www/anbcoder/.venv/lib/python3.8/site-packages/pystray/_base.py", line 368, in __call__
return self._action(icon, self)
File "/www/anbcoder/main.py", line 65, in <lambda>
lambda icon, item: icon.remove_notification()))))).run()
File "/www/anbcoder/.venv/lib/python3.8/site-packages/pystray/_base.py", line 239, in remove_notification
self._remove_notification()
File "/www/anbcoder/.venv/lib/python3.8/site-packages/pystray/_util/gtk.py", line 84, in _remove_notification
self._notifier.hide()
File "/www/anbcoder/.venv/lib/python3.8/site-packages/pystray/_util/notify_dbus.py", line 89, in hide
GLib.Variant(
File "/usr/lib/python3/dist-packages/gi/overrides/GLib.py", line 189, in __new__
v = creator._create(format_string, value)
File "/usr/lib/python3/dist-packages/gi/overrides/GLib.py", line 132, in _create
raise TypeError("Could not create array, tuple or dictionary entry from non iterable value %s %s" %
TypeError: Could not create array, tuple or dictionary entry from non iterable value (u) 83
Process finished with exit code 130 (interrupted by signal 2: SIGINT)
I'm running exactly the code from the documentation example:
icon('test', Image.open(r'myproject-favicon.png'), menu=menu(
item(
'With submenu',
menu(
item(
'Show message',
lambda icon, item: icon.notify('Hello World!')),
item(
'Submenu item 2',
lambda icon, item: icon.remove_notification()))))).run()
The tray shows up, the hello world notification shows up, but when pressing the remove notification button, it gives me this error and nothing happens.
I am using Gnome 3 and for my app I would like to have really simple function for tray icon: if I click on icon, the app will show its window, if I click on tray icon again, the app will hide its window. I can do this, but not just with click, just with menu - but I want no menu, just click. Double click dont work too. Still will just open menu. But if I click on menu item, it is working good, but I would like to work without menu.
Here is my code:
from` pystray import Icon as icon, Menu as menu, MenuItem as item
from PIL import Image, ImageDraw, ImageFont
import time
def create_image():
# Generate an image and draw a pattern
font = ImageFont.truetype("/usr/share/fonts/liberation/LiberationSans-Regular.ttf", 90)
img = Image.new("RGB", (100, 100), "white")
img.putalpha(0)
d = ImageDraw.Draw(img)
d.text((0,0), "50", font=font, fill='red')
return img
from kivy.clock import Clock
from kivy.app import App
from kivy.config import Config
from kivy.uix.textinput import TextInput
from threading import Thread
Config.set('graphics', 'window_state', 'hidden')
Config.set('graphics', 'borderless', '1')
Config.set('kivy', 'exit_on_escape', '0')
class MyDebugApp(App):
visible = False
def build(self):
return TextInput()
def on_start(self):
self.root.focus = True
def alternate(self):
if self.visible:
self.root.get_root_window().hide()
else:
self.root.get_root_window().show()
self.visible = not self.visible
ma = MyDebugApp()
kivy_app = Thread(target=ma.run)
kivy_app.start()
my_menu = menu(item(text="Show Main Window", action=ma.alternate, default = True, visible=False))
icon = icon('EasyBright', create_image(), menu=my_menu)
icon.run()
I am dynamically updating the icon image in a thread as suggested in #30 and it works well. Thank you.
During runtime a copy of the current image is created with a random name at /tmp/tmp*
. Each time the icon changes, it appears the old file is deleted and a new file is created with a new random name.
However, each time the below code is run, a copy of the icon image is left behind on exit. If the script runs 100 times, then 100 temporary files are left behind.
It seems there is something missing in cleanup of the icon image on exit?
This code tests whether a VPN network interface is up or not, however you can change the path
to any test file then create and delete that test file to test the functionality. The actual VPN does not matter. I am using Ubuntu 18.04.
#!/usr/bin/python3
import os
import time
from PIL import Image
from pystray import Icon, Menu, MenuItem
from threading import Thread
path = "/sys/class/net/tun0/operstate"
imagedn = Image.open("/usr/share/icons/gnome/16x16/status/user-busy.png")
imageup = Image.open("/usr/share/icons/gnome/16x16/status/user-available.png")
def check_vpn(icon):
while True:
if os.path.isfile(path):
if icon.icon is not imageup:
icon.icon = imageup
else:
if icon.icon is not imagedn:
icon.icon = imagedn
time.sleep(0.5)
def loop(icon):
icon.visible = True
thread = Thread(target=check_vpn, args=([icon]), daemon=True)
thread.start()
def exit_action(icon):
icon.stop()
icon = Icon(name="VPN Status Icon", icon=imagedn, menu=Menu(MenuItem("Exit", lambda : exit_action(icon))))
icon.run(setup=loop)
I want to declare Icon and provide menu later. I intend to pass icon explicitly along with some other variables to act on extra variables using user actions.
I directly imported pystray after installing with pip3
ImportError: this platform is not supported
I'm currently on ubuntu.
Doing a little digging, I went through the imports one by one and found Xlib is not installed.
pip3 install python3-xlib
ah... I think I see how this is a problem.
Since python-xlib does not install on python3,
and python3-xlib does not installl on python2,
trying to create a universal pystray will fail since you can't require the same type of packages.
I think getting a more informative error (in case an import fails) would be useful.
I'd like to open a window when a menu on the icon is clicked.
I've been playing around with tk, but I have a hard time getting tk and pystray to work at the same time since both assume that they control the event loop.
Do you have any recommendations how I could make this work?
mbarkhau@mbarkhau-vbox:~/pystray$ python3 -m unittest tests/icon_tests.py
/usr/local/lib/python3.6/site-packages/Xlib/xauth.py:45: ResourceWarning: unclosed file <_io.BufferedReader name='/home/mbarkhau/.Xauthority'>
raw = open(filename, 'rb').read()
/usr/local/lib/python3.6/site-packages/Xlib/protocol/rq.py:1012: DeprecationWarning: tostring() is deprecated. Use tobytes() instead.
v, l, fm = f.pack_value(field_args[f.name])
/usr/local/lib/python3.6/site-packages/Xlib/protocol/rq.py:707: DeprecationWarning: tostring() is deprecated. Use tobytes() instead.
data, dlen, fmt = PropertyData.pack_value(self, value)
Failed to dock icon
Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/pystray/_xorg.py", line 140, in _show
self._assert_docked()
File "/usr/local/lib/python3.6/site-packages/pystray/_xorg.py", line 385, in _assert_docked
assert self._systray_manager
AssertionError
Click the icon
Hi,
I am trying to run the app from a thread.
There is a random error(happens 8 of 10 times).
WindowsError: exception: access violation reading 0x00007FFC0000C2FD
I am sharing the icon with other threads via globals. So have to initialize it with
icon = None
I suspect this is the reason, where a main thread variable is being used by sub-threads.
How to overcome?
A trycatch points to
Error: exception: access violation reading 0x00007FFC0000C2FD
Traceback (most recent call last):
File "pystrayTest.py", line 366, in run_icon
MenuItem('Exit',on_exit)))
File "C:\Python27\lib\site-packages\pystray_win32.py", line 60, in init
self._menu_hwnd = self._create_window(self._atom)
File "C:\Python27\lib\site-packages\pystray_win32.py", line 226, in _create_w
indow
None)
WindowsError: exception: access violation reading 0x00007FFC0000C2FD
Hello,
Thanks for this outstanding work, this is a nice cross-platform and lightweight package,
I was looking for a lightweight systray that can work with tkinter and yours was my first choice until i found something in documentation says that pystray must run from main loop, then i decided to use "infi.systray" which supports windows only, everything works on windows flawlessly no issues,
Then i tried to find a way to run your pystray from a thread, and finally it did work "I didn't know before that main thread is the requirement for mac only", and i have to create menu and run icon from same thread.
everything works well with pystray on windows, however i miss 2 features:
1- set/update tooltip, in infi.systray i can use systray.update(hover_text='my tooltip')
2- Double-click
which, I hope you could add support for both.
here is an example code, where I run Icon from a thread "not worry about mac support right now"
from PIL import Image
import threading, io, base64
from pystray import Icon, Menu, MenuItem
APP_ICON2 = b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAKfSURB\nVDiNZdNfaNVlHAbwz/n9zu/M6Vz7o41yzplg4BCFolbZWi2FiBIMvQq9qJAuCokugqCWFAgJxSgS\n+kN5Uxb9uVJyVgc0wgg65UpczLl2HHPacM7z23bmOaeLnU6bvlcP7/s8z/d5X94n4Ya1dz3Fp9GF\n1vLmORzDB3T3zWcn/oc9VYy/hd3tssEWAxrErgmNqpHW6he3FnAAL9Cdn2fQU8X4keXiB/f7Vrus\nvFBOSiwSi8wI9Wv0pvuMq/4ej9CdD+cM7n5nmXj7576wsTaW7HpIPEtuqiBXCORErkoJlHT420nN\nq6cl60kfSZTvnPnYN8H9hjR8ckDdzh3Ge08I6m7y444XXTw3VkmSkzItaZ9NBYINIQ+83C7b/pyT\n8ktqBW1trmROyzy7V76YkGxeIZs5WxHHIqGiCYuCC5bMJPHwFgPyQqWWVv2v9ohFZmvrrdy51eFt\nLy0Qz+HF1rvgd02bA7Q0mhKLXDo9VCHd/voembcPuThyuSKeSVXLlc+TirAqQOmaxHUTIi3bugxn\nzspJKdXVe+y9PfZPfqnj+a1zCQVQSmJ4VM26+eJYZOzUgMe/3mes/7zGtSt99cqnzvx23rK1K8Qi\n0VyC4SR6f7B63T2GK+JY5ND217Q8usn4pdip42dM5BOeeONJhw/+pEZev0Y4GtKZHbF090ajQaBU\nMbiSDwz+MWJ48B+ThVAssripwWQ+ITk0qNeaAp4JSY/RefOvbrmrw5BJVTe8x3+4r2/MnctnfTTS\nZEbyXboPln9i57Ep0b0/a75tg1GBksuqF4iXmtFs0ocjTSYs+g67SBfKBukCnZ9NiepPWHXHVVVB\nvWlVCiJFoZK/NDpqTWFusl3XlWlBndsoPoXN5TonMFiu8/t0/zmf/S9tcxBW9J/R4gAAAABJRU5E\nrkJggg==\n'
def create_image():
buffer = io.BytesIO(base64.b64decode(APP_ICON2))
img = Image.open(buffer)
return img
def quit(icon, item):
icon.stop()
def show():
print('show main window')
def create_icon():
# i can use one click using default=True, but no option for double-click
menu = Menu(MenuItem("Start / Show", show, default=True), MenuItem("Minimize to Systray",
lambda: None), MenuItem("Close to Systray", lambda: None), MenuItem("Quit", quit))
icon = Icon('test', create_image(), menu=menu)
return icon
def foo():
print('start icon')
icon = create_icon()
icon.run()
threading.Thread(target=foo).start()
Hello,
Is it possible to list all systray icons (even the ones started by an other process) ?
Hi guys,
I am facing an issue where my application goes missing from the system tray, but it is running properly when viewing in task manager. The issue is not persistent . If I restart my application trayicon appears again.
This is my code to make the icon visible.
icon = pystray.Icon('test name')
icon.visible = True
This is the stack trace of the error which I guess is the root of the issue
File "C:\Python34\lib\site-packages\pystray\_base.py", line 153, in visible
self._show()
File "C:\Python34\lib\site-packages\pystray\_win32.py", line 75, in _show
szTip=self.title)
File "C:\Python34\lib\site-packages\pystray\_win32.py", line 296, in _message
**kwargs))
OSError: exception: access violation reading 0x00000000049D1008.
This is the function which fails
win32.Shell_NotifyIcon(code, win32.NOTIFYICONDATA(
cbSize=ctypes.sizeof(win32.NOTIFYICONDATA),
hWnd=self._hwnd,
hID=id(self),
uFlags=flags,
**kwargs))
Please help me to resolve the issue.
Thanks
I'm spelunking through the library source in hopes of finding the reason for a mysterious GTK crash... and saw something weird:
def run(self, setup=None):
...
self._run()
self._running = True
_run()
only returns once stop()
is called, so if stop()
is called from the setup thread, it will first set _running
to False, and then run()
will set it back to True after _run()
returns.
_running
is later used in __del__
in _win32.py
and _xorg.py
to decide whether to call stop()
.
I suspect this is unintended, though I'm not able to test on Windows to tell what the effects of changing it would be.
Hello again!
The latest update did, indeed, fix the HAS_NOTIFICATION issue. Thank you for the quick fix! :)
However, I run into an issue where no error is reported, but a notification is not displayed.
This can be reproduced by simply putting icon.Notify("msg")
in the setup callback.
Thank you!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.