Reputation: 6205
I am trying to get a dynamic text displayed in the system tray (this will be 2 numbers (from 1 to 100) changing every 2 minutes).
I found this script as a starting point (but I am not commited to it!).
But I get this error :
TypeError: Image.SetData(): arguments did not match any overloaded call:
overload 1: argument 1 has unexpected type 'str'
overload 2: argument 1 has unexpected type 'str'
OnInit returned false, exiting...
The relevant part of the code is:
def Get(self,l,r):
s=""+self.s_line
for i in range(5):
if i<(5-l):
sl = self.sl_off
else:
sl = self.sl_on
if i<(5-r):
sr = self.sr_off
else:
sr = self.sr_on
s+=self.s_border+sl+self.s_point+sr+self.s_point
s+=self.s_border+sl+self.s_point+sr+self.s_point
s+=self.s_line
image = wx.EmptyImage(16,16)
image.SetData(s)
bmp = image.ConvertToBitmap()
bmp.SetMask(wx.Mask(bmp, wx.WHITE)) #sets the transparency colour to white
icon = wx.EmptyIcon()
icon.CopyFromBitmap(bmp)
return icon
I add to update the script by adding import wx.adv
and by replacing the 2 wx.TaskBarIcon
by wx.adv.TaskBarIcon
.
I am on Windows 10 with Python 3.6
Upvotes: 2
Views: 2879
Reputation: 22438
The following uses the current minute and second as a replacement for your line numbers but can be easily adapted.
import wx
import wx.adv
import datetime
from wx.lib.embeddedimage import PyEmbeddedImage
#
# A white box 28x28 pixels
#
toggletest = PyEmbeddedImage(
b'iVBORw0KGgoAAAANSUhEUgAAABwAAAAcCAIAAAD9b0jDAAAACXBIWXMAAAsTAAALEwEAmpwY'
b'AAAAB3RJTUUH4wMfCgElTFaeRQAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJ'
b'TVBkLmUHAAAAKElEQVRIx2P8//8/A7UBEwMNwKiho4aOGjpq6Kiho4aOGjpq6OAzFADRYgM1'
b'8cIRtgAAAABJRU5ErkJggg==')
class TaskBarIcon(wx.adv.TaskBarIcon):
def __init__(self, frame):
self.frame = frame
self.toggle = 0
wx.adv.TaskBarIcon.__init__(self)
self.Bind(wx.adv.EVT_TASKBAR_LEFT_DOWN, self.OnToggle)
self.font = wx.SystemSettings.GetFont(wx.SYS_SYSTEM_FONT)
self.font.SetPointSize(8)
self.OnSetIcon(self.NewIcon())
def CreatePopupMenu(self):
menu = wx.Menu()
togglem = wx.MenuItem(menu, wx.NewId(), 'Toggle Icon')
menu.Bind(wx.EVT_MENU, self.OnToggle, id=togglem.GetId())
menu.Append(togglem)
menu.AppendSeparator()
flashm = wx.MenuItem(menu, wx.NewId(), 'Flashing Icon')
menu.Bind(wx.EVT_MENU, self.OnTimer, id=flashm.GetId())
menu.Append(flashm)
menu.AppendSeparator()
quitm = wx.MenuItem(menu, wx.NewId(), 'Quit')
menu.Bind(wx.EVT_MENU, self.OnQuit, id=quitm.GetId())
menu.Append(quitm)
return menu
def NewIcon(self):
bitmap = wx.Bitmap(toggletest.Bitmap)
dc = wx.MemoryDC(bitmap)
# Use current time as text, for want of something useful
now = datetime.datetime.today()
text = str(now.minute)+"\n"+str(now.second)
dc.SetFont(self.font)
dc.DrawText(text, 2, 2)
del dc
return bitmap
def OnSetIcon(self, bitmap):
icon = wx.Icon()
icon.CopyFromBitmap(bitmap)
self.SetIcon(icon)
def OnToggle(self, event):
bitmap = self.NewIcon()
self.OnSetIcon(bitmap)
def OnTimer(self,event):
self.timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.OnUseTimer)
self.timer.Start(1000)
def OnUseTimer(self,event):
self.OnToggle(None)
def OnQuit(self, event):
self.RemoveIcon()
wx.CallAfter(self.Destroy)
self.frame.Close()
if __name__ == '__main__':
app = wx.App()
frame=wx.Frame(None)
TaskBarIcon(frame)
app.MainLoop()
The result is the white box below with 22 above 33
Upvotes: 5
Reputation: 6205
I found another way using Pillow
and infi.systray
# text to image : Pillow (https://pillow.readthedocs.io/en/latest/handbook/tutorial.html - simple code sample: https://code-maven.com/create-images-with-python-pil-pillow)
# icon in systray : infi.systray (https://github.com/Infinidat/infi.systray and https://stackoverflow.com/a/54082417/3154274)
# inspired by https://www.reddit.com/r/learnpython/comments/a7utd7/pystray_python_system_tray_icon_app/
# install PIL : pip install Pillow
# install infi.systray : pip install infi.systray
from infi.systray import SysTrayIcon
from PIL import Image, ImageDraw,ImageFont
import time
image= "pil_text.ico"
n=1
while True:
# create image
img = Image.new('RGBA', (50, 50), color = (255, 255, 255, 90)) # color background = white with transparency
d = ImageDraw.Draw(img)
d.rectangle([(0, 40), (50, 50)], fill=(39, 112, 229), outline=None) # color = blue
#add text to the image
font_type = ImageFont.truetype("arial.ttf", 25)
a= n*10
b = n*20
d.text((0,0), f"{a}\n{b}", fill=(255,255,0), font = font_type)
img.save(image)
# display image in systray
if n==1:
systray = SysTrayIcon(image, "Systray")
systray.start()
else:
systray.update(icon=image)
time.sleep(5)
n+=1
systray.shutdown()
Upvotes: 4