Home > Net >  How to use multiple arguments calling a function in Pystray?
How to use multiple arguments calling a function in Pystray?

Time:11-26

I'm trying to pass extra arguments to a function that is called by an item in pystray menu.

import pystray
from pystray import MenuItem as item
from PIL import Image, ImageTk

def show_window(icon):
    icon.notify('Hello World!', 'Hi')


def quit_window(icon, message):
    print(message)
    icon.stop()


icon = 'icon.ico'
image=Image.open(icon)

menu=pystray.Menu(item('Show', show_window, default=True), item('Quit', quit_window(icon, "Test")))
icon=pystray.Icon("name", image, "My System Tray Icon", menu)
icon.run()

In this example I'm trying to pass the argument "message" calling the function "quit_window" when I press "Quit" in pystray menu. The problem here is by default the functions used in menu construction don't have arguments and internally refers to icon. When I use arguments the constructor don't pass the icon reference to call stop() and since I create pystray.Icon after pystray.Menu I don't know how to pass this info and make it work.

CodePudding user response:

You can sort of do what you appear to want to do but not like that.

The item() takes a function (like show_window, note no brackets) not a function call like you used quit_window(icon,message) - but if you make the called function return a function then it will indirectly do what you want, although the message is fixed at compile time.

Or you could make the function use a global to get the message it prints, which is a bit horrible but means the message is runtime changeable. Or you could probably do something with a class which at least wouldn't use an explicit global.

Anyway those tow methods are shown here (i renamed all those references to icon because it was confusing):

import pystray
from pystray import MenuItem as item
from PIL import Image, ImageTk

def show_window(icon1):
    icon1.notify('Hello World!', 'Hi')

globalmessage = "A global quit message"

def quit_window(icon2):
    icon2.stop()

def indirect_quit_window(icon2,message):
    print( f"The message on quit will be '{message}'" )
    def realquitfunction(icon2):
        print( message )
        icon2.stop()
    return realquitfunction


def global_quit(icon4):
    global globalmessage
    print( globalmessage )
    icon4.stop()

icon = 'icon.ico'
image=Image.open(icon)

menu=pystray.Menu(item('Show', show_window, default=True), item('Quit', indirect_quit_window(icon, "Quitting now - bye!")),item('Global Quit', global_quit) )

icon3=pystray.Icon("name", image, "My System Tray Icon", menu)
icon3.run()

Output when starting then clicking Quit:

The message on quit will be 'Quitting now - bye!'
Quitting now - bye!

Output when starting then clicking Global Quit:

The message on quit will be 'Quitting now - bye!'
A global quit message
  • Related